简体   繁体   中英

Javascript or JQuery JSON Object grouping

I have a JSON data like this

[
{"attributes":{"SHAPELEN":26.2293318917963,"CITYID":2061}},
{"attributes":{"SHAPELEN":16.9352548253636,"CITYID":2062}},
{"attributes":{"SHAPELEN":22.101151804600597,"CITYID":2063}},
{"attributes":{"SHAPELEN":22.8809188858315,"CITYID":2061}},
{"attributes":{"SHAPELEN":18.6906905910402,"CITYID":2063}},
{"attributes":{"SHAPELEN":31.322932493622,"CITYID":2062}},
{"attributes":{"SHAPELEN":10.5580020747299,"CITYID":2063}},
]

And I wanna group this data by CITYID and sum SHAPELENs like this.

[
{CITYID:2061, TOTAL=49.1},
{CITYID:2062, TOTAL=47.2},
{CITYID:2063, TOTAL=51,34}
]

I created a javascript function but did not work that I Want to.

function gropData(data) {
    var features = data.features;
    var cities = [];

    $.each(features, function (index, item) {
        // **if cities not include item, add in cities. But if not working here**
        if (!$.inArray(item.attributes, cities) ) { 
            cities.push(item.attributes);
        }

    });
 }

Is there a soluton that you see?

$.inArray() is a terribly-named function. It doesn't return a bool, it returns the index of the item if found in the array, or -1 if the item isn't found. So if an item isn't found, checking for truthy-ness will return true. If the item is the first in the array, it will evaluate to false.

You need to do this instead:

if ($.inArray(item.attributes, cities) < 0) {
    // item not found
    cities.push(item.attributes);
}

if ($.inArray(item.attributes, cities) == -1) { also works if that's easier for you to read/understand.

You cannot search an array for an objects value, you either need to loop through the array to check each object manually or use jQuery's $.grep function. Also, data.features does not exist in your JSON object above, you may want to just do a $.each on data itself.

    var result = $.grep(cities, function(e){ return e.CITYID == item.attributes.CITYID; });
    if(result.length == 0){
        var tempItem = { CITYID : item.attributes.CITYID, TOTAL : item.attributes.SHAPELEN };
        cities.push(tempItem);
    }else{
        result[0].TOTAL += item.attributes.SHAPELEN;
    }

Also a pure JavaScript version:

function groupData(data) {
  var cities = [];
  data.forEach(function(datum) {
    var cityEntry,
        attr = datum.attributes;
    cities.some(function(city) {
      if (city.CITYID === attr.CITYID) {
        cityEntry = city;
        return true;
      }});

    if (cityEntry) {
      cityEntry.TOTAL += attr.SHAPELEN;
    } else {
      cities.push({CITYID: attr.CITYID, 
                   TOTAL: attr.SHAPELEN});
    }
  });
  return cities;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM