对嵌套数组进行分组

Grouping a nested array

Fiddle Example

我在 d3.js 中有一个由 nest 方法生成的数组 任何人都可以建议一种 javascript/jQuery 方法来对 values 属性 中的对象进行分组吗category?

var data = [
  {
    "key": "0",
    "values": [
      {
        "category": "phone",
        "brand": "Sony",
        "brand_id": "0",
        "name": "item A",
        "id": "551",
        "point": "600"
      },
      {
        "category": "software",
        "brand": "Sony",
        "brand_id": "0",
        "name": "item D",
        "id": "51",
        "point": "800"
      },
      {
        "category": "phone",
        "brand": "Sony",
        "brand_id": "0",
        "name": "item E",
        "id": "52",
        "point": "1800"
      }
    ]
  },
  {
    "key": "0",
    "values": [
      {
        "category": "software",
        "brand": "Microsoft",
        "brand_id": "1",
        "name": "item B",
        "id": "54",
        "point": "800"
      },
      {
        "category": "phone",
        "brand": "Microsoft",
        "brand_id": "1",
        "name": "item B",
        "id": "60",
        "point": "200"
      },
      {
        "category": "phone",
        "brand": "Microsoft",
        "brand_id": "1",
        "name": "item T",
        "id": "30",
        "point": "600"
      },
      {
        "category": "software",
        "brand": "Microsoft",
        "brand_id": "1",
        "name": "item N",
        "id": "90",
        "point": "500"
      }
    ]
  }
];

这是一个想要的结果:

[
  {
    "key": "0",
    "values": [
      {
        "phone": [
          {
            "category": "phone",
            "brand": "Sony",
            "brand_id": "0",
            "name": "item A",
            "id": "551",
            "point": "600"
          },
          {
            "category": "phone",
            "brand": "Sony",
            "brand_id": "0",
            "name": "item E",
            "id": "52",
            "point": "1800"
          }
        ],
        "software": [
          {
            "category": "software",
            "brand": "Sony",
            "brand_id": "0",
            "name": "item D",
            "id": "51",
            "point": "800"
          }
        ]
      }
    ]
  },
  {
    "key": "0",
    "values": [
      {
        "phone": [
          {
            "category": "phone",
            "brand": "Microsoft",
            "brand_id": "0",
            "name": "item B",
            "id": "80",
            "point": "54"
          },
          {
            "category": "phone",
            "brand": "Microsoft",
            "brand_id": "0",
            "name": "item D",
            "id": "52",
            "point": "1800"
          }
        ],
        "software": [
          {
            "category": "software",
            "brand": "Microsoft",
            "brand_id": "0",
            "name": "item G",
            "id": "41",
            "point": "800"
          },
          {
            "category": "software",
            "brand": "Microsoft",
            "brand_id": "0",
            "name": "item L",
            "id": "42",
            "point": "900"
          }
        ]
      }
    ]
  }
]

以下代码无效。我想这是因为 grouped[t.category] = [] 在每个循环中都定义了。前一项将被最后一项覆盖。如果我没有定义它,我会得到一个 grouped[t.category] 未定义的错误:

grouped = {};
data.forEach(function(d){
  d.values.map(function(t){ 
     grouped[t.category] = [];       
     grouped[t.category].push({name:t.name,tid:t.id,point:parseInt(t.point)});
   })
})

试试这个

var grouped;

data.forEach(function(d) {
    grouped = {};

    d.values.forEach(function(t) {
         if (!grouped[t.category]) {
             grouped[t.category] = [];
         }

         grouped[t.category].push({
             name:  t.name,
             tid:   t.id, 
             point: parseInt(t.point)
         });
     })

    d.values = grouped;
});

Example

你可以试试这个: jsfiddle

var result = data.map(function ( record ) {
    return {
        key:    record.key,
        values: [ groupBy( 'category', record.values ) ]
    };
})

function groupBy ( key, arr ) {
    var groups = {};
    arr.forEach(function ( el ) {
        var keyVal = el[ key ];
        if ( !keyVal ) return;

        if ( groups[ keyVal ] )
            groups[ keyVal ].push( el );
        else
            groups[ keyVal ] = [ el ];
    });
    return groups;
}

你可以用lodash或类似的库

这样解决
_.map(data, function(x){
  return _.assign({}, x, {values: _.groupBy(x.values, 'category')})
})

Fiddle

我熟悉underscore.js:

var desireResult = _.map(data, function(obj){
    obj.values = _.groupBy(obj.values, 'category');
    return obj;
});

希望对您有所帮助!