我想知道如何执行以下分组并总结Underscore或Lodash。
MY ARRAY:
[
{_id : "1", S : "2"},
{_id : "1", M : "4"},
{_id : "2", M : "1"},
{_id : "" , M : "1"},
{_id : "3", S : "3"}
]
渴望输出
[
{_id : "1", M : "4", S : "2", Total: "6"},
{_id : "2", M : "1", S : "0", Total: "1"},
{_id : "3", M : "0", S : "3", Total: "3"},
{_id : "", M : "1", S : "0", Total: "1"}
]
我到目前为止
我坚信我到目前为止做了以下事情,但我无法弄清楚我的内容是什么?
var groups = _.groupBy(MyArray, function(value){
return value._id;
});
var data = _.map(groups, function(group){
return {
_id: group[0]._id,
M: ?? ,
S: ?? ,
T: ??
}
});
答案 0 :(得分:1)
使用普通javascript解决方案,使用Array.prototype.forEach
和Array.prototype.map
函数
var obj = {}
// arr is your first array
arr.forEach(function(a) {
var t = obj[a._id];
if (t) {
t.M += a.M ? parseInt(a.M, 10) : 0;
t.S += a.S ? parseInt(a.S, 10) : 0;
t.Total = parseInt(t.M, 10) + parseInt(t.S, 10);
} else {
t = {};
t._id = a._id;
t.M = a.M ? parseInt(a.M, 10) : 0;
t.S = a.S ? parseInt(a.S, 10) : 0;
t.Total = parseInt(t.M, 10) + parseInt(t.S, 10);
obj[a._id] = t;
}
});
var res = Object.keys(obj).map(function (k) {
return obj[k];
})
console.log(res);
结果:
[ { _id: '1', M: 4, S: 2, Total: 6 },
{ _id: '2', M: 1, S: 0, Total: 1 },
{ _id: '3', M: 0, S: 3, Total: 3 },
{ _id: '', M: 1, S: 0, Total: 1 } ]
答案 1 :(得分:0)
这是一个普通Javascript中的提案,带有一个临时对象和一些数组方法。
var data = [{ _id: "1", S: "2" }, { _id: "1", M: "4" }, { _id: "2", M: "1" }, { _id: "", M: "1" }, { _id: "3", S: "3" }],
result = function (data) { // immediately invoked function expression
var r = [], o = {}; // declare the result and temp object
data.forEach(function (a) { // iterate over data
if (!o[a._id]) { // check if id in object
o[a._id] = { // if not build new object
_id: a._id, // with the wanted properties
M: 0, // _id, a value taken for the key, too
S: 0, // M and S initialized with 0
Total: 0 // Total as well initialised with 0
}; // push the reference of object to result
r.push(o[a._id]); // while we reference an object, the values
} // are the same in object o and in array r
['M', 'S'].forEach(function (k) { // iterate over M and S, the keys to sum
o[a._id][k] += +a[k] || 0; // add truthy value or 0 to group
o[a._id].Total += +a[k] || 0; // take value or the default value 0 with
}); // a logical or
}); // end of iteration
return r; // return result
}(data);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
答案 2 :(得分:0)
使用链式lodash
,v3.10.1
,groupBy()
thru()
,keys()
和{{1}的reduce()
find()
兼容版本}}:
merge()
答案 3 :(得分:0)
array = [
{_id : "1", S : "2"},
{_id : "1", M : "4"},
{_id : "2", M : "1"},
{_id : "" , M : "1"},
{_id : "3", S : "3"}
];
array.reduce(function(previousValue, currentValue){
var existingObj = previousValue.find(function(obj){
return obj._id == currentValue._id;
});
if(existingObj){
Object.assign(existingObj, currentValue);
existingObj.total = +(existingObj.M) + +(existingObj.S);
}else{
if(currentValue.M){
currentValue.total = currentValue.M;
}else if(currentValue.S){
currentValue.total = currentValue.S;
}
previousValue.push(currentValue);
}
return previousValue;
},[]);
答案 4 :(得分:0)
这是一个非常简洁的lodash解决方案:
_(data).groupBy("_id").map((group, id) => { //group is an array of items with the same id
const mTotal = _.sum(_.map(group, (item) => parseInt(item.M) || 0));
const sTotal = _.sum(_.map(group, (item) => parseInt(item.S) || 0));
return {
_id: id,
M: mTotal.toString(),
S: sTotal.toString(),
Total: (mTotal + sTotal).toString()
}
}).value() //End lodash chain
旁注:通过不将字符串转换为数字,你会让事情变得更难。