如何通过键减少对象数组并在javascript中求和

时间:2018-07-23 14:10:34

标签: javascript arrays lodash javascript-objects

我正试图解决这个问题

var crates = [{category: "fruits", type: "apple", color: "green", number: 1}, 
             {category: "fruits", type: "apple", color: "red", number: 1},
             {category: "fruits", type: "banana", color: "yellow", number: 1}, 
             {category: "vegetables", type: "onion", color: "white", number: 1}]

对此:

var stand = [{category: "fruits", type: "apple", sum: 2}, 
             {category: "fruits", type: "banana", sum: 1}, 
             {category: "vegetables", type: "onion", sum: 1}]

使用lodash / fp。到目前为止,我已经做了很多尝试,这是我设法获得的最接近的结果:

var stand = flow(
      groupBy('type'),
      map((objs, key) => ({
          'category': key,
          'type': key,
          'sum': _.sumBy(objs, 'number') }))
    )(crates);

结果为:

[{category: undefined, type: undefined, sum: 2},
{category: undefined, type: undefined, sum: 1}
{category: undefined, type: undefined, sum: 1}]

很明显,我不知道如何将对“ category”和“ type”值的引用传递给map函数。

我是不熟悉lodash / fp的新手,并为整个fp概念而苦苦挣扎,所以我很高兴能为我指明正确的方向!

3 个答案:

答案 0 :(得分:0)

在lodash-fp中,方法的固定系数为1(回调接收1个参数)以支持自动计数。这意味着map的回调没有获得密钥。您可以从组中的第一个对象获得typecategory

要允许切换sumBy()参数,因此objs应该是第二个参数:

const { flow, groupBy, map, sumBy } = _;

const crates = [{"category":"fruits","type":"apple","color":"green","number":1},{"category":"fruits","type":"apple","color":"red","number":1},{"category":"fruits","type":"banana","color":"yellow","number":1},{"category":"vegetables","type":"onion","color":"white","number":1}];

const result = flow(
  groupBy('type'),
  map((objs) => ({
    'category': objs[0].category,
    'type': objs[0].type,
    'sum': sumBy('number', objs)
  }))
)(crates);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-fp/0.10.4/lodash-fp.js"></script>

答案 1 :(得分:0)

这是我使用Array.reduce和Array.findIndex的解决方案。

var crates = [{ category: "fruits", type: "apple", color: "green", number: 1 },
{ category: "fruits", type: "apple", color: "red", number: 1 },
{ category: "fruits", type: "banana", color: "yellow", number: 1 },
{ category: "vegetables", type: "onion", color: "white", number: 1 }]


console.log(
    crates.reduce(
        (crates, item) => {
            const index = crates.findIndex(i => {
                return i.type == item.type && i.category == item.category
                }
            )
            if (index > -1) crates[index].sum += item.number
            else { crates.push({ type: item.type, category: item.category, sum: item.number }) }
            return crates;
        }, [])
);

虽然它比lodash更为冗长,但是学习标准数组方法来解决问题将使您对第三方库的依赖性降低。

答案 2 :(得分:0)

作为一个初学者,我在@mpm上工作:认为这是编写自己的lodash实用程序版本的实践机会。这是一个MASSIVE库,您可能不会充分利用它来证明将其添加到package.json中的依赖项是合理的。这是又分为两个步骤的另一种方法,首先将输入数组分解为一个对象(具有各种水果类型),然后将新对象推入输出数组:

const standMaker = (crates) => {
  var fruits = {};
  for (let fruit of crates) {
    if (!fruits[fruit.type]) {
      fruits[fruit.type] = {};
      fruits[fruit.type].sum = 1;
      fruits[fruit.type].category = fruit.category;
    } else if (fruits[fruit.type]) {
      fruits[fruit.type].sum += 1;
    }
  };
  var stand = [];
  for (let fruit in fruits) {
    stand.push({category: fruits[fruit].category, type: fruit, sum: fruits[fruit].sum});
  }
  console.log(stand);
}