【问题标题】:sum up object properties in array of objects into a single object Lodash将对象数组中的对象属性汇总为单个对象 Lodash
【发布时间】:2016-11-21 18:29:42
【问题描述】:

我一直在努力解决这个问题并且遇到了问题,所以我想我应该向有更多经验的人询问。我有一个对象数组,可以说称为项目,我需要总结数组中不同对象的一些属性,并在最后总结它们。用户可以进行一些选择,我只需要总结他们给我的数组中唯一选择的属性,所以我想也许可以在 lodash 中使用 _.pick 函数。如果可能的话,我想在一个循环中执行此操作,因为 items 数组最多可以有 1000 个项目。这是一个例子:

var items = [
{'lightBlue':4, 'darkBlue':2, 'red':4, 'orange':6, 'purple':7},
{'lightBlue':6, 'darkBlue':5, 'red':1, 'orange':2, 'purple':3},
{'lightBlue':2, 'darkBlue':4, 'red':3, 'orange':4, 'purple':9}
]

var userSelectedColors = ['lightBlue', 'darkBlue'];

我想看到的是所有蓝色的总结如下:

var summedUp = [{'lightBlue':12, 'darkBlue':11}];

然后将结果相加得到总数

var totalCount = 23

在 lodash. userSelectedColors 数组可以是 1 或颜色的任意组合。

请提供示例,感谢您的帮助!

【问题讨论】:

  • 除非items 非常非常大,否则性能可能不会成为问题。非 lodash 解决方案可能是最快的。
  • 嗨,谢谢@4castle,你能提供一个例子来说明如何得到我上面提到的结果吗?

标签: javascript arrays underscore.js lodash


【解决方案1】:

使用_.sumBy

var totalCount = _.sumBy(userSelectedColors, _.partial(_.sumBy, items));

var items = [
  { 'lightBlue': 4, 'darkBlue': 2, 'red': 4, 'orange': 6, 'purple': 7 },
  { 'lightBlue': 6, 'darkBlue': 5, 'red': 1, 'orange': 2, 'purple': 3 },
  { 'lightBlue': 2, 'darkBlue': 4, 'red': 3, 'orange': 4, 'purple': 9 }
], userSelectedColors = ['lightBlue', 'darkBlue'];

var totalCount = _.sumBy(userSelectedColors, _.partial(_.sumBy, items));

console.log(totalCount);
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>

展开,看起来像:

var totalCount = _.sumBy(userSelectedColors, function(prop) {
    return _.sumBy(items, prop);
});

如果没有 Lodash,性能更高的解决方案将是这样的:

var totalCount = items.reduce(function(total, obj) {
    return total + userSelectedColors.reduce(function(total, prop) {
        return total + obj[prop];
    }, 0);
}, 0);

var items = [
  { 'lightBlue': 4, 'darkBlue': 2, 'red': 4, 'orange': 6, 'purple': 7 },
  { 'lightBlue': 6, 'darkBlue': 5, 'red': 1, 'orange': 2, 'purple': 3 },
  { 'lightBlue': 2, 'darkBlue': 4, 'red': 3, 'orange': 4, 'purple': 9 }
], userSelectedColors = ['lightBlue', 'darkBlue'];

var totalCount = items.reduce(function(total, obj) {
    return total + userSelectedColors.reduce(function(total, prop) {
        return total + obj[prop];
    }, 0);
}, 0);

console.log(totalCount);
<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>

【讨论】:

  • 实际上,这并不能让您访问摘要 ({ lightBlue: 12, darkBlue: 13 })。也许我误解了这个问题?
  • @smarx 嗯,OP选择了它,也许他们真的只关心totalCount
  • @4castle 我想是的。我已经删除了我的答案,但如果事实证明需要摘要,我可以恢复它。 :-)
  • 是的@smarx 我只是想解释这个过程,最终我想要总和。
  • @jamesemanon 当然。这是我从 Haskell 学到的一种函数式编程技术。将回调的第一个参数应用到嵌套的_.sumBy 的第二个参数只是一种简短的说法。我进行了编辑以显示更多内容。
【解决方案2】:

就效率而言,我相信这很难被击败,因为它只在数组中迭代一次,但它不像@4castle 所采用的方法那样简洁。 (另外,对于只有 1000 个项目,无论如何您都不会注意到性能差异。)

var items = [
    {'lightBlue':4, 'darkBlue':2, 'red':4, 'orange':6, 'purple':7},
    {'lightBlue':6, 'darkBlue':5, 'red':1, 'orange':2, 'purple':3},
    {'lightBlue':2, 'darkBlue':4, 'red':3, 'orange':4, 'purple':9}
]

var userSelectedColors = ['lightBlue', 'darkBlue'];

var sums = {};

_.each(items, function (item) {
    _.each(userSelectedColors, function (color) {
        sums[color] = (sums[color] || 0) + item[color];
    });
});

console.log('Summary: ', sums);

console.log('Grand total: ', _.sum(_.values(sums)));

输出:

Summary:  { lightBlue: 12, darkBlue: 11 }
Grand total:  23

【讨论】:

  • 太棒了,谢谢!我正在寻找没有嵌套循环的东西,(我有类似的东西,只是使用 lodash forEach)。无论如何,非常感谢你帮助我!
【解决方案3】:

获取摘要

var summary = userSelectedColors.map(c => ({ [c]: _.sumBy(items, c)}))

总计

var total = _.sum(Object.values(summary))

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-20
  • 1970-01-01
  • 1970-01-01
  • 2020-01-10
相关资源
最近更新 更多