带有lodash /下划线的复合索引

时间:2014-12-24 08:56:18

标签: javascript indexing underscore.js lodash compound-index

当处理来自数据库的数据时,我们经常得到一些东西,由于数据库的限制,这些东西可以被复合索引(唯一地)索引。但是,indexBy似乎不适用于复合索引,或者它是否适用?

给定一个数组x,其对象具有属性ab,我希望有一个字典词典,其中包含x的所有对象,由{建立索引分别为{1}}和a。例如:

Fiddle here

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确实支持复合指数),还是至少可以改进?

1 个答案:

答案 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']));

演示http://jsfiddle.net/nikoshr/8w4n31vb/