var data = [
{id: 1, quantity: 10, category: 'A'},
{id: 2, quantity: 20, category: 'B'},
{id: 1, quantity: 30, category: 'A'},
{id: 1, quantity: 30, category: 'Z'},
{id: 2, quantity: 40, category: 'D'}
];
var totalPerType = {};
for (var i = 0, len = data.length; i < len; ++i) {
totalPerType[data[i].id] = totalPerType[data[i].id] || 0;
totalPerType[data[i].id] += data[i].quantity;
}
var out = _.map(totalPerType, function (id, quantity) {
return {'id': id, 'quantity': quantity};
});
console.log(out);
我的代码目前总结了具有相同ID的对象的数量。它返回
[ {id:1, quantity:70}, {id:2, quantity:60} ]
如何根据ID和类别获取对象的总和?
例如,我需要这样的输出:
[
{id:1, quantity:40, category:A},
{id:1, quantity:30, category:Z},
{id:2, quantity:20, category:B},
{id:, quantity:40, category:D}
]
我想要简单的javascript和下划线的答案。
答案 0 :(得分:3)
使用vanilla js。
var tmp = {}
data.forEach(function (item) {
var tempKey = item.id + item.category;
if (!tmp.hasOwnProperty(tempKey)) {
tmp[tempKey] = item;
} else {
tmp[tempKey].quantity += item.quantity;
}
});
var results = Object.keys(tmp).map(function(key){
return tmp[key];
});
请注意,这将更改原始数据中的对象。在添加到item
对象时,如果不需要,则需要复制tmp
var data = [
{id: 1, quantity: 10, category: 'A'},
{id: 2, quantity: 20, category: 'B'},
{id: 1, quantity: 30, category: 'A'},
{id: 1, quantity: 30, category: 'Z'},
{id: 2, quantity: 40, category: 'D'}
];
var tmp = {}
data.forEach(function (item) {
var tempKey = item.id + item.category;
if (!tmp.hasOwnProperty(tempKey)) {
tmp[tempKey] = item;
} else {
tmp[tempKey].quantity += item.quantity
}
});
var results = Object.keys(tmp).map(function(key){
return tmp[key];
});
document.body.innerHTML ='<pre>' + JSON.stringify(results,null,4) +'</pre>';
&#13;
答案 1 :(得分:1)
以下是使用下划线的解决方案:
// used when calling reduce to sum the quantities of a group of items
var sumQuantity = function(total, item){
return total + item.quantity;
}
// used by groupBy to create a composite key for an item
var itemKey = function(item){
return item.id + '/' + item.category;
}
// used to convert a group of items to a single item
var groupToSummedItem = function(group){
return {
id: group[0].id,
category: group[0].category,
quantity: _.reduce(group, sumQuantity, 0)
}
}
// the bit that does the work
var result = _.chain(data)
.groupBy(itemKey)
.map(groupToSummedItem)
.value();
答案 2 :(得分:1)
已经有两个好的答案,但我想我会展示一个更灵活的ES6解决方案。它使用Map
并通过从需要匹配的属性创建字符串为每条记录创建唯一键。使用键将记录添加到地图中,并根据需要对值进行求和。
完成后,它将地图转换为数组并返回新数组;
var data = [ // test data
{id: 1, quantity: 10, category: 'A'},
{id: 2, quantity: 20, category: 'B'},
{id: 2, quantity: 20, category: 'Z'},
{id: 2, quantity: 20, category: 'D'},
{id: 1, quantity: 30, category: 'A'},
{id: 1, quantity: 30, category: 'Z'},
{id: 2, quantity: 40, category: 'D'}
];
// function to collapse records in an array of objects;
// arr is the array of objects
// match is an array of property names that need to be matched
// sum us an array of property names that need to be summed
function collapse ( arr, match, sum ) { // bad name but just can't remember what this should be called
// define vars
var newArray, key, processRecord
// define function
// function to process each record
processRecord = function( item ) {
// define vars
var key, getKey, sumFields, record;
// define functions
getKey = function ( field ) { key += item[field]; } // Creates a key
sumFields = function ( field ) { record[field] += item[field];} // sums fields
// code
key = ""; // create a blank key
match.forEach( getKey ); // create a unique key
if(newArray.has( key ) ){ // does it exist
record = newArray.get( key ); // it does so get the record
sum.forEach( sumFields ); // sum the fields
}else{
newArray.set( key, item ); // the key does not exist so add new record
}
}
// code
newArray = new Map(); // create a new map
arr.forEach( processRecord ); // process each record
return ( [...newArray.values()] ); // convert map to array and return it
}
// call the function matching id and category summing quantity
var a1 = collapse( data, ["id" , "category"], ["quantity"] );
// call the function matching id only summing quantity
var a2 = collapse( data, ["id"], ["quantity"] );
// call the function matching category only summing quantity
var a3 = collapse( data, ["category"], ["quantity"] );
// call the function matching all fields and summing quantity
var a4 = collapse( data, ["id, "quantity", "category"], ["quantity"] );