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

时间:2017-05-02 00:22:04

标签: javascript arrays merge count lodash

给出以下对象数组:

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'
  }
]

我需要将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
  },
]

最简单的方法是什么?我偏爱Lodash,但我对其他选择持开放态度。使用_.groupBy(),我可以将所有内容与项目组合在一起作为对象键:

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

但这只会让我分道扬..在这里搜索我看到_.reduce()(或只是普通.reduce())或_.map()的很多用途,但我无法理解如何使用它们这个案例。如果我尝试使用与_.groupBy()链接的_.map()

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

执行甚至没有到我的地图功能,所以我不确定我做错了什么。

感谢。

4 个答案:

答案 0 :(得分:5)

_.groupBy链接的

_.map是最简单的解决方案。 _.map的正确回调函数是:

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

或者你可以使用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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如果你想在不使用loadash的情况下这样做,这将创建所需的数组:

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()]);

答案 2 :(得分:0)

使用_.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();

答案 3 :(得分:0)

我最终选择了这个:

has_many :incomes
has_many :expences

  def all_incomes
      incomes.map(&:amount).sum
  end
  def all_expences
      expences.map(&:amount).sum
  end
  def balance
    all_incomes - all_expences
  end
end