对对象数组中的相似键求和 In javascript
Sum similar keys in an array of objects In javascript
我有一个对象数组,如下所示:-
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"}
我想对相似的键求和得到
预期输出:
1: {Id: 0, count1: 25, count2: 10}
2: {Id: 1, count1: 1100, count2: 402}
是否可以使用任何数学运算或 reduce 或任何其他 javascript 方法来实现它?
谢谢
您可以通过使用散列 table 和一个键数组来对所需值求和来减少数组。
var data = [{ 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" }],
keys = ['count1', 'count2'],
grouped = Object.values(data.reduce((result, object) => {
result[object.Id] = result[object.Id] || { Id: object.Id };
keys.forEach(key => result[object.Id][key] = (result[object.Id][key] || 0) + object[key]);
return result;
}, Object.create(null)));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
通过敲除,您可以使用一系列计算属性来获得所需的(UI?)格式!
免责声明:我假设此列表不会包含数千个项目
1。分组
第一步是从项目列表 (ko.observableArray([])
) 到按 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>
2。合并
现在我们已经对需要汇总的项目列表进行了分组,我们可以开始应用合并逻辑了:
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 })
)
3。从索引对象返回到数组
现在我们知道如何合并我们的组,我们可以回到我们在 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>
我有一个对象数组,如下所示:-
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"}
我想对相似的键求和得到 预期输出:
1: {Id: 0, count1: 25, count2: 10}
2: {Id: 1, count1: 1100, count2: 402}
是否可以使用任何数学运算或 reduce 或任何其他 javascript 方法来实现它?
谢谢
您可以通过使用散列 table 和一个键数组来对所需值求和来减少数组。
var data = [{ 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" }],
keys = ['count1', 'count2'],
grouped = Object.values(data.reduce((result, object) => {
result[object.Id] = result[object.Id] || { Id: object.Id };
keys.forEach(key => result[object.Id][key] = (result[object.Id][key] || 0) + object[key]);
return result;
}, Object.create(null)));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
通过敲除,您可以使用一系列计算属性来获得所需的(UI?)格式!
免责声明:我假设此列表不会包含数千个项目
1。分组
第一步是从项目列表 (ko.observableArray([])
) 到按 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>
2。合并
现在我们已经对需要汇总的项目列表进行了分组,我们可以开始应用合并逻辑了:
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 })
)
3。从索引对象返回到数组
现在我们知道如何合并我们的组,我们可以回到我们在 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>