当处理来自数据库的数据时,我们经常得到一些东西,由于数据库的限制,这些东西可以被复合索引(唯一地)索引。但是,indexBy
似乎不适用于复合索引,或者它是否适用?
给定一个数组x
,其对象具有属性a
和b
,我希望有一个字典词典,其中包含x
的所有对象,由{建立索引分别为{1}}和a
。例如:
b
var x = [
{
a: 1,
b: 11,
c: 101
},
{
a: 2,
b: 11,
c: 101
},
{
a: 1,
b: 11,
c: 102
},
{
a: 1,
b: 14,
c: 102
},
];
// index x by a, then by b, then by c
var byABC = _.compoundIndexBy(x, ['a', 'b', 'c']);
// there are two items in `x` with a = 1 and b = 11
console.assert(_.size(byABC[1][11]) == 2, 'Something went wrong...');
// display result
console.log(byABC);
现在看起来像这样:
byABC
This Fiddle演示{
1: {
11: {
101: {
a: 1,
b: 11,
c: 101
},
102: {
a: 1,
b: 11,
c: 102
}
},
14: {
102: {
a: 1,
b: 14,
c: 102
}
},
}
2: {
11:{
101: {
a: 2,
b: 11,
c: 101
}
}
}
}
函数。我的工作是徒劳的(因为Lo-Dash确实支持复合指数),还是至少可以改进?
答案 0 :(得分:1)
您可以创建一个以递归方式对对象进行分组/索引的mixin:
_.mixin({
compoundIndexBy: function(lst, iteratees, context) {
if (iteratees.length === 1)
return _.indexBy(lst, iteratees[0], context);
var grouped = _.groupBy(lst, iteratees[0], context);
_.each(grouped, function(sublst, k) {
grouped[k] = _.compoundIndexBy(sublst, _.rest(iteratees), context);
});
return grouped;
}
});
console.dir(_.compoundIndexBy(x, ['a', 'b', 'c']));
如果您更喜欢与给定索引匹配的对象列表(例如,在非唯一路径的情况下):
_.mixin({
compoundGroupBy: function(lst, iteratees, context) {
var grouped = _.groupBy(lst, iteratees[0], context);
if (iteratees.length === 1)
return grouped;
_.each(grouped, function(sublst, k) {
grouped[k] = _.compoundGroupBy(sublst, _.rest(iteratees), context);
});
return grouped;
}
});
console.dir(_.compoundGroupBy(x, ['a', 'b', 'c']));