我一直在努力完成这项任务,但我似乎无法找到“正确的方法”去做,昨天我在这里要求修复我用纯javascript制作的代码,我得到了这个答案在我的旧question [已编辑]上使用下划线;
_.chain(arr)
.groupBy(function(a) {return a.idBox; })
.toArray()
.map(function(es, i) {
return (es[0].idBox) ? {id: i, group: es[0].idBox, date: es[0].date , entries: es} : _.extend({id: i}, es[0]);
})
.value()
不幸的是,它与我的情况无法正常工作,我遇到的第一个问题是它不维护原始排序(按日期,日期是从mysql已经排序的desc中检索的),其次是似乎如果有多个idBox的对象:null,第一个将生成它,但其他的(作为null)将不会使它成为value()。我正在创建一个新问题,因为它的上下文/问题本身非常不同,可能对其他人创建一个单独的问题更有帮助。
输入
[
{
id: 1,
idbox: null,
date: ""
},
{
id: 4,
idbox: 1,
date: ""
},
{
id: 3,
idbox: 1,
date: ""
},
{
id: 2,
idbox: null,
date: ""
},
{
id: 0,
idbox: 1,
date: ""
},
{
id: 5,
idbox: 2,
date: ""
}
]
预期产出;
[
{
id: 1,
idbox: null,
date: ""
},
{
box: 1,
objects: [ [Object], [Object], [Object] ]
},
{
id: 2,
idbox: null,
date: ""
},
{
box: 2,
objects: [ [Object] ]
}
]
实际输出;
[
{
box: 1,
date: "",
objects: [ [Object], [Object], [Object] ]
},
{
box: 2,
date: "",
objects: [ [Object] ]
},
{
id: 1,
idbox: null,
date: ""
}
]
答案 0 :(得分:0)
fold
或reduce
是您的朋友。
arr = your_original_array
_.reduce(arr, function(memo, a) {
if (a.idbox == null) {
memo.push(a);
} else {
b = _.find(memo, function(c) { return c.box == a.idbox });
if (!b) {
b = {box: a.idbox, objects: []};
memo.push(b)
}
b.objects.push(a)
}
return memo
}, []);
您可以加快速度(如果原始数组中有数千条记录):
_.reduce(arr, function(memo, a) {
if (a.idbox == null) {
memo.result.push(a);
} else {
b = memo.dict[a.idbox]
if (!b) {
b = { box: a.idbox, objects: [] };
memo.result.push(b);
memo.dict[a.idbox] = b;
}
b.objects.push(a);
}
return memo;
}, {dict: {}, result: []}).result;
reduce
函数对数组中的每个元素进行操作。
reduce
函数有两个参数:
一个函数,它接受最后生成的结果(Underscore.js调用此memo
)和当前元素。它以某种方式(检查函数体)将当前元素和最后一个结果组合成一个新结果。并且新结果将再次作为memo
传递给该函数,并使用下一个项目,依此类推......
备忘录的初始值
由于reduce逐个元素地遍历数组,因此该代码保留了顺序而无需引入排序键。