简体   繁体   English

按值合并数组中的对象并获取每个对象的计数

[英]Merge objects in array by value and get count for each

Given the following array of objects:给定以下对象数组:

myArray = [
  {
    item: 'Item 1',
    material: 'Material1',
    type: 'head'
  },
  {
    item: 'Item 1',
    material: 'Material1',
    type: 'head'
  },
  {
    item: 'Item 2',
    material: 'Material2',
    type: 'shell'
  },
  {
    item: 'Item 1',
    material: 'Material1',
    type: 'head'
  },
  {
    item: 'Item 2',
    material: 'Material2',
    type: 'shell'
  },
  {
    item: 'Item 3',
    material: 'Material3',
    type: 'support'
  },
  {
    item: 'Item 1',
    material: 'Material1',
    type: 'head'
  },
  {
    item: 'Item 3',
    material: 'Material3',
    type: 'support'
  },
  {
    item: 'Item 2',
    material: 'Material2',
    type: 'shell'
  }
]

I need to combine these by the item value with a count so that I get an array that looks like this:我需要将这些按item值与计数结合起来,以便得到一个如下所示的数组:

var myResultArray = [
  {
    item: 'Item 1',
    material: 'Material1',
    type: 'head'
    count: 4
  },
  {
    item: 'Item 2',
    material: 'Material2',
    type: 'shell'
    count: 3
  },
  {
    item: 'Item 3',
    material: 'Material3',
    type: 'support'
    count: 2
  },
]

What is the easiest way to do this?最简单的方法是什么? I'm partial to Lodash, but I'm open to other alternatives.我偏爱 Lodash,但我对其他选择持开放态度。 With _.groupBy() I can get everything grouped together with the item as the object key:使用_.groupBy()我可以将所有内容与项目组合在一起作为对象键:

var myGrouped = _.groupBy(myArray, 'item');

but that only gets me part way there.但这只会让我走到那一步。 Searching around here I see a lot of uses of _.reduce() (or just plain .reduce() ) or _.map() , but I haven't been able to get my head around exactly how to use them in this case.在这里搜索我看到很多_.reduce() (或只是普通的 .reduce .reduce() )或_.map()的用途,但我一直无法确切地了解如何在此使用它们案件。 If I try to use _.groupBy() chained with _.map() like so如果我尝试像这样使用_.groupBy()_.map() ) 链接

var myGrouped = _(myArray).groupBy('item').map(function(item) {
                  // do stuff here
                });

the execution doesn't even get to my map function, so I'm not sure what I'm doing wrong.执行甚至没有到达我的地图功能,所以我不确定我做错了什么。

Thanks.谢谢。

_.groupBy chained with _.map is the simplest solution. _.groupBy_.map链接是最简单的解决方案。 A proper callback function for the _.map would be: _.map的适当回调函数是:

function (items) {
  items[0].count = items.length;
  return items[0];
}

Or you could condense it further with ES6 arrow-functions.或者你可以用 ES6 箭头函数进一步压缩它。

 const myArray = [{"item":"Item 1","material":"Material1","type":"head"},{"item":"Item 1","material":"Material1","type":"head"},{"item":"Item 2","material":"Material2","type":"shell"},{"item":"Item 1","material":"Material1","type":"head"},{"item":"Item 2","material":"Material2","type":"shell"},{"item":"Item 3","material":"Material3","type":"support"},{"item":"Item 1","material":"Material1","type":"head"},{"item":"Item 3","material":"Material3","type":"support"},{"item":"Item 2","material":"Material2","type":"shell"}]; const myResultArray = _(myArray).groupBy('item').map(items => (items[0].count = items.length, items[0])).value(); console.log(myResultArray);
 <script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>

If you want to do it without using Lodash, this would create the required array:如果您想在不使用 Lodash 的情况下执行此操作,这将创建所需的数组:

const res = myArray.reduce((accum, val) => {
  let summary = accum.get(val.item) || Object.assign({}, val, {count:0});
  summary.count++;
  return accum.set(val.item, summary);
}, new Map());

console.log([...res.values()]);

I ended up going with this:我最终选择了这个:

var groupedData = [];
_(typeData).groupBy('item').forEach(function(value, key) {
  var obj = {};  
  obj.count = value.length;
  obj.type = value[0].type;
  obj.details = value[0].details;
  obj.description = key;
  groupedData.push(obj);
});                 

using _.countBy and _.uniqBy使用_.countBy_.uniqBy

var res = _.chain(myArray)
    .countBy('item') // get each item count
    .thru(counts => // counts = {Item 1: 4, Item 2: 3, Item 3: 2}
        _.chain(myArray)
            .uniqBy('item') // get uniq items
            .map(item =>  // set each item count
                _.assign(
                    item, 
                    {count: counts[item.item]}
                );
            )
            .value();
    )
    .value();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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