javascript | Object grouping

后端 未结 10 1247
不思量自难忘°
不思量自难忘° 2020-11-27 05:29

I have an object. It looks like below:

[
  {
    \"name\":\"Display\",
    \"group\":\"Technical detals\",
    \"id\":\"60\",
    \"value\":\"4\"
  },
  {
           


        
相关标签:
10条回答
  • 2020-11-27 05:59

    You could use a hash table for the groups and Array#forEach for iterating the array.

    Then check if the hash exist and if not assign an empty array to it and push it to the result set.

    Later push the actual element to the array of the hash.

    function groupBy(array, group) {
        var hash = Object.create(null),
            result = [];
    
        array.forEach(function (a) {
            if (!hash[a[group]]) {
                hash[a[group]] = [];
                result.push(hash[a[group]]);
            }
            hash[a[group]].push(a);
        });
        return result;
    }
    
    var data = [{ name: "Display", group: "Technical detals", id: 60, value: 4 }, { name: "Manufacturer", group: "Manufacturer", id: 58, value: "Apple" }, { name: "OS", group: "Technical detals", id: 37, value: "Apple iOS" }];
    	
    console.log(groupBy(data, "group"));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    0 讨论(0)
  • 2020-11-27 06:01

    If you're using underscore.js in your application then you can simply do the following:

    var groups = _.groupBy(data, 'group'); // data is your initial collection
    

    Or if you prefer not to use any library then you can do it yourself:

    var groups = { };
    data.forEach(function(item){
       var list = groups[item.group];
    
       if(list){
           list.push(item);
       } else{
          groups[item.group] = [item];
       }
    });
    

    You can see both examples in action http://jsfiddle.net/nkVu6/3/

    0 讨论(0)
  • 2020-11-27 06:04

    Try with something like this:

    function groupBy(collection, property) {
        var i = 0, val, index,
            values = [], result = [];
        for (; i < collection.length; i++) {
            val = collection[i][property];
            index = values.indexOf(val);
            if (index > -1)
                result[index].push(collection[i]);
            else {
                values.push(val);
                result.push([collection[i]]);
            }
        }
        return result;
    }
    
    var obj = groupBy(list, "group");
    

    Keep in mind that Array.prototype.indexOf isn't defined in IE8 and older, but there are common polyfills for that.

    0 讨论(0)
  • 2020-11-27 06:09

    I tried to use the answer marked as accepted, but noticed that there were elements missing in some groups, depending on the type of property being evaluated. This is a solution derived from that answer:

    function groupBy(collection, property) {
      var i = 0, values = [], result = [];
      for (i; i < collection.length; i++) {
        if(values.indexOf(collection[i][property]) === -1) {
          values.push(collection[i][property]);
          result.push(collection.filter(function(v) { return v[property] === collection[i][property] }));
        }
      }
      return result;
    }
    var obj = groupBy(list, "group");
    
    0 讨论(0)
  • 2020-11-27 06:10

    If you like working with ES6 Map, then this is for you:

    function groupBy(arr, prop) {
        const map = new Map(Array.from(arr, obj => [obj[prop], []]));
        arr.forEach(obj => map.get(obj[prop]).push(obj));
        return Array.from(map.values());
    }
    
    const data = [{ name: "Display", group: "Technical detals", id: 60, value: 4 }, { name: "Manufacturer", group: "Manufacturer", id: 58, value: "Apple" }, { name: "OS", group: "Technical detals", id: 37, value: "Apple iOS" }];
    	
    console.log(groupBy(data, "group"));
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    The Map instance is created from key/value pairs that are generated from the input array. The keys are the values of the property to group by, and the values are initialised as empty arrays.

    Then those arrays are populated. Finally the values of the map (i.e. those populated arrays) are returned.

    0 讨论(0)
  • 2020-11-27 06:11

    A bit different way, so we have a plain list of objects, and want to group it per property, but includes all related

    const data = [{'group':'1', 'name':'name1'},
    {'group':'2', 'name':'name2'},
    {'group':'2', 'name':'name3'},
    ,{'group':'1', 'name':'name4'}]; 
    
    const groups = data .map( i => i.group);
    const uniqueGroups = Array.from(new Set(groups));
    const groupes = uniqueGroups.map( c => { 
                return  { group:c, names:[]};
            } ); 
    
    group.forEach( g => { 
                groupes.find( gg => gg.group === g.group).names.push(g.name);
    });
    

    so result would be like:

    [ {'group':'1', 'names':['name1', 'name4']},
    {'group':'2', 'names':['name2', 'name3']}
    
    0 讨论(0)
提交回复
热议问题