在javascript中将对象数组中的相似键求和 [英] Sum similar keys in an array of objects In javascript

查看:50
本文介绍了在javascript中将对象数组中的相似键求和的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一系列类似于以下内容的对象:-

I have an array of objects something like the following: -

0: {Id: 0, count1: 5, count2: 10, yearMonth: "201803"}
1: {Id: 0, count1: 10, count2: 0, yearMonth: "201804"}
2: {Id: 1, count1: 900, count2: 200, yearMonth: "201805"}
3: {Id: 0, count1: 10, count2: 0, yearMonth: "201806"}
4: {Id: 1, count1: 100, count2: 100, yearMonth: "201807"}
5: {Id: 1, count1: 100, count2: 2, yearMonth: "201808"}

我想对相似的密钥求和以获得 预期输出:

I want to sum similar keys to get Expected output:

1: {Id: 0, count1: 25, count2: 10}
2: {Id: 1, count1: 1100, count2: 402}

是否可以使用任何数学运算或归约或任何其他javascript方法来实现?

Is it possible to achieve it using any mathematical operation or reduce or any other javascript method?

谢谢

推荐答案

通过剔除,您可以使用一系列计算属性来获得所需的(UI?)格式!

With knockout, you can use a chain of computed properties to get to the desired (UI?) format!

免责声明:我假设此列表将不包含数千个项目

第一步是从项目列表(ko.observableArray([]))转到按ID分组的计算对象:

The first step is to go from a list (ko.observableArray([])) of items to a computed object that groups by id:

// Search for "group by javascript" to have this function explained
const groupBy = (prop, xs) => xs.reduce(
  (acc, x) => Object.assign(acc, { [x[prop]]: (acc[x[prop]] || []).concat(x) }), {}
);

const items = ko.observableArray([]);

const itemsById = ko.pureComputed(() =>
  groupBy("Id", items())
);

itemsById.subscribe(console.log);
items([{Id: 0, count1: 5, count2: 10, yearMonth: "201803"},{Id: 0, count1: 10, count2: 0, yearMonth: "201804"},{Id: 1, count1: 900, count2: 200, yearMonth: "201805"},{Id: 0, count1: 10, count2: 0, yearMonth: "201806"},{Id: 1, count1: 100, count2: 100, yearMonth: "201807"},{Id: 1, count1: 100, count2: 2, yearMonth: "201808"}]);

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

现在,我们已经将需要汇总的项目列表进行了分组,我们可以开始应用合并逻辑:

Now that we have grouped lists of items that need to be summarized, we can start applying our merge logic:

const itemsWithSameId = [{Id:0,count1:5,count2:10,yearMonth:"201803"},{Id:0,count1:10,count2:0,yearMonth:"201804"},{Id:0,count1:10,count2:0,yearMonth:"201806"}];

const merge = (itemA, itemB) => ({
  Id: itemB.Id,
  count1: itemA.count1 + itemB.count1,
  count2: itemA.count2 + itemB.count2
});

// Look up "merging objects using reduce in javascript" to find out more
console.log(
  itemsWithSameId.reduce(merge, { count1: 0, count2: 0 })
)

现在我们知道如何合并组了,我们可以返回到UI中需要的数组:

Now that we know how to merge our groups, we can move back to the array we need in our UI:

// Utilities:
const groupBy = (prop, xs) => xs.reduce(
  (acc, x) => Object.assign(acc, {
    [x[prop]]: (acc[x[prop]] || []).concat(x)
  }), {}
);

// Data Logic:
const merge = (itemA, itemB) => ({
  Id: itemB.Id,
  count1: itemA.count1 + itemB.count1,
  count2: itemA.count2 + itemB.count2
});

// App
const items = ko.observableArray([]);
const itemsById = ko.pureComputed(() =>
  groupBy("Id", items())
);

// Look up "mapping over the values of a javascript object" for more info
const summedItems = ko.pureComputed(() =>
  Object
    .values(itemsById())
    .map(items => items.reduce(merge, { count1: 0, count2: 0 }))
);

// Apply bindings with viewmodel exposing summedItems
ko.applyBindings({ summedItems });

// Inject data (probably in success callback of ajax call)
items([{Id: 0, count1: 5, count2: 10, yearMonth: "201803"},{Id: 0, count1: 10, count2: 0, yearMonth: "201804"},{Id: 1, count1: 900, count2: 200, yearMonth: "201805"},{Id: 0, count1: 10, count2: 0, yearMonth: "201806"},{Id: 1, count1: 100, count2: 100, yearMonth: "201807"},{Id: 1, count1: 100, count2: 2, yearMonth: "201808"}]);

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<table>
  <thead>
    <tr>
      <th>Id</th>
      <th>Count 1</th>
      <th>Count 2</th>
    </tr>
  </thead>
  <tbody data-bind="foreach: summedItems">
    <td data-bind="text: Id"></td>
    <td data-bind="text: count1"></td>
    <td data-bind="text: count2"></td>
  </tbody>
</table>

这篇关于在javascript中将对象数组中的相似键求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆