【问题标题】:Group objects within nested arrays into array of sub-totals by common property按公共属性将嵌套数组中的对象分组为小计数组
【发布时间】:2020-06-23 20:08:22
【问题描述】:

我有一个我找不到解决方法的问题。 我有一堆按属性分组的数组:

[
  [
    {Id: '211321', SendFrom: 'Customer 1', Price: 120, Amount: 2},
    {Id: '211341', SendFrom: 'Customer 1', Price: 320, Amount: 5},
    {Id: '212351', SendFrom: 'Customer 1', Price: 300, Amount: 2},
    {Id: '234121', SendFrom: 'Customer 1', Price: 230, Amount: 3},
    {Id: '223321', SendFrom: 'Customer 1', Price: 410, Amount: 1}
  ],
  [
    {Id: '2321', SendFrom: 'Customer 2', Price: 120, Amount: 2},
    {Id: '21341', SendFrom: 'Customer 2', Price: 320, Amount: 5},
    {Id: '2351', SendFrom: 'Customer 2', Price: 300, Amount: 2},
    {Id: '4121', SendFrom: 'Customer 2', Price: 230, Amount: 3},
    {Id: '3321', SendFrom: 'Customer 2', Price: 410, Amount: 1}
  ],
  [
    {Id: '3453', SendFrom: 'Customer 3', Price: 520, Amount: 2},
    {Id: '4334', SendFrom: 'Customer 3', Price: 220, Amount: 5},
    {Id: '2343', SendFrom: 'Customer 3', Price: 700, Amount: 2},
    {Id: '6654', SendFrom: 'Customer 3', Price: 430, Amount: 3},
    {Id: '4534', SendFrom: 'Customer 3', Price: 210, Amount: 1}
  ]
]

在此示例中,对象按 SendFrom 属性分组。

我想做的是创建一个像这样的对象:

[
  {SendFrom: 'Customer 1', Price: 1380, Amount: 13},
  {SendFrom: 'Customer 2', Price: 1380, Amount: 13},
  {SendFrom: 'Customer 3', Price: 2080, Amount: 13}
]

新对象保留原始的 SendFrom 值,但包含 Price 和 Amount 属性的更新值。

我怎样才能用 JavaScript 或 lodash 的帮助得到这个?

最好的问候, 美国

【问题讨论】:

  • 您的输入看起来不正确。它既不是数组也不是对象。此外,您没有指定“如何”更新输出。它是否总是将一组中的所有价格和金额相加?
  • 嗨,Rahul,是的,它总是将一组中的所有价格和金额相加。关于输入,我几乎可以肯定它是一个对象数组,但我可能是错的。
  • 查看下面的@Nina Scholz 解决方案。它非常好,似乎也修复了输入。

标签: javascript arrays object lodash


【解决方案1】:

您可以使用一个对象进行分组并将所有想要的值添加到它们的属性中。最后只取对象的值。

var data = [[{ Id: '211321', SendFrom: 'Customer 1', Price: 120, Amount: 2 }, { Id: '211341', SendFrom: 'Customer 1', Price: 320, Amount: 5 }, { Id: '212351', SendFrom: 'Customer 1', Price: 300, Amount: 2  }, { Id: '234121', SendFrom: 'Customer 1', Price: 230, Amount: 3 }, { Id: '223321', SendFrom: 'Customer 1', Price: 410, Amount: 1 }], [{ Id: '2321', SendFrom: 'Customer 2', Price: 120, Amount: 2 }, { Id: '21341', SendFrom: 'Customer 2', Price: 320, Amount: 5 }, { Id: '2351', SendFrom: 'Customer 2', Price: 300, Amount: 2 }, { Id: '4121', SendFrom: 'Customer 2', Price: 230, Amount: 3 }, { Id: '3321', SendFrom: 'Customer 2', Price: 410, Amount: 1 }], [{ Id: '3453', SendFrom: 'Customer 3', Price: 520, Amount: 2 }, { Id: '4334', SendFrom: 'Customer 3', Price: 220, Amount: 5 }, { Id: '2343', SendFrom: 'Customer 3', Price: 700, Amount: 2  }, { Id: '6654', SendFrom: 'Customer 3', Price: 430, Amount: 3 }, { Id: '4534', SendFrom: 'Customer 3', Price: 210, Amount: 1 }]],
    grouped = Object.values(data.flat().reduce((r, { SendFrom, Price, Amount }) => {
        r[SendFrom] = r[SendFrom] || { SendFrom, Price: 0, Amount: 0 };
        r[SendFrom].Price += Price;
        r[SendFrom].Amount += Amount;
        return r;
    }, {}));

console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 谢谢,这符合我的需要。并感谢@Yevgen 的解释。我要把它保存下来研究它,它很好用,如果我了解它的工作原理就更好了
  • @AmericoPerez :感谢您的回复,希望您在我删除答案时复制了您需要的内容
【解决方案2】:
var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};

console.log(groupBy(your_array_name, 'SendFrom'));

【讨论】:

  • 建议解释您的代码如何解决/解决 OP 的问题。仅代码的答案不受欢迎。添加信息可以让访问者快速放大重要部分,更快地进行认知消化,并帮助激发访问者学习并将知识应用到他们自己的代码中。这有利于知识问答,而不是“给我代码”作为服务问答。它还保持了 SO 作为平台的高质量。
【解决方案3】:
var groupBy = function(xs, key) {
  return xs.reduce(function(rv, x) {
    (rv[x[key]] = rv[x[key]] || []).push(x);
    return rv;
  }, {});
};

console.log(groupBy(['one', 'two', 'three'], 'length'));

// => {3: ["one", "two"], 5: ["three"]}

【讨论】:

  • 考虑为您的答案添加一些解释。
猜你喜欢
  • 2020-11-12
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
相关资源
最近更新 更多