假设我有一个集合
var data = [
{ fieldA: 5 },
{ fieldA: 142, fieldB: 'string' },
{ fieldA: 1324, fieldC: 'string' },
{ fieldB: 'string', fieldD: 111, fieldZ: 'somestring' },
...
];
让我们假设各个元素的字段不一致,但我事先知道唯一字段的数量,并且该集合不是动态的。
我想用_.findWhere
之类的东西过滤它。这很简单,但如果我想优先考虑速度优先呢?是否有更好的数据结构,总是最小化将要检查的元素数量?也许某种树?
答案 0 :(得分:1)
是的,如果您的查询属于“使用fieldX = valueY给我所有记录”,那么会有更快的速度。但是,它确实有开销。
对于每个字段,构建一个倒排索引,列出具有每个值的所有记录ID(=原始data
中的行位置):
var indexForEachField = {
fieldA: { "5": [0], "142": [1], "1324": [2]},
...
}
当有人要求“其中fieldX = valueY的记录”时,您将返回
indexForEachField["fieldX"]["valueY"]; // an array with all results
因此查找时间不变(并且表中只需要2次查找),但您需要保持索引最新。
这是搜索引擎使用某些术语查找网页的策略的概括;在那种情况下,它被称为inverted index。
编辑:如果您想查找fieldX = valueX 和 fieldY = valueY的所有记录,该怎么办?
您将使用以下代码,该代码需要所有输入数组 待分类:
var a = indexForEachField["fieldX"]["valueX"];
var b = indexForEachField["fieldY"]["valueY"];
var c = []; // result array: all elements in a AND in b
for (var i=0, j=0; i<a.length && j<b.length; /**/) {
if (a[i] < b[j]) {
i++;
} else if (a[i] > b[j]) {
j++;
} else {
c.push(a[i]);
i++; j++;
}
}
你可以看到,在最坏的情况下,总复杂度正是a.length + b.length
;而且,在最好的情况下,一半。您可以使用非常类似的东西来实现OR。