我希望有一组对象,按一些数字属性val
排序。我希望能够检索匹配val
与某些值匹配的所有对象,例如x
,或者如果没有对象val
匹配x
,则查找对象距离val
上方和下方最近的x
。 (多个对象可能具有val
)
我发现的为数不多的BST库之一是dsjslib。它具有所谓的TreeMultiMap
,它为单个键保存多个值。问题是如果没有完全匹配,我无法看到如何检索最接近x
的节点。
我怎么能这样做?浏览器对ES6的支持似乎有很长的路要走,所以也许我可以使用它的Map
来做这个?
答案 0 :(得分:0)
这听起来像是在二元搜索之后。我为Arrays开发了一个二进制findIndex
方法,当然它在排序数组中工作。它需要一个回调,并且在它的帮助下,也可以搜索排序的对象数组。由于它是二进制搜索,因此比标准findIndex
或indexOf
方法快得多。
默认回调是x => x
,如果没有提供回调,它会默认处理已排序的原语。如果它找到搜索到的对象,它的当前状态会返回它的索引,但如果没有,它将返回-1。如果搜索到它可以很容易地修改以返回接近指数。如果您需要,我可以稍后再添加。
Array.prototype.sortedFindIndex = function(val, cb = x => x) { // default callback for primitive arrays
var deli = this.length-1, // delta index
base = 0; // base to add the delta index
while (deli > 0 && cb(this[base + deli]) != val) {
deli = ~~(deli/2);
cb(this[base + deli]) < val && (base += deli);
}
return cb(this[base + deli]) === val ? base + deli : -1;
};
arr = [{a:0,b:"foo"},{a:1,b:"bar"},{a:2,b:"baz"},{a:3,b:"qux"},{a:4,b:"fox"},{a:5,b:"pun"},{a:6,b:"alf"}],
idx = arr.sortedFindIndex(4, o => o.a);
console.log(idx);
这是一个修改后的版本,可以更巧妙地处理故障情况。如果找不到搜索到的项目,则以下代码段将返回应该存在的索引的否定值。棘手的部分。如果缺少的项目应该插入索引0,它将返回负零(-0)。现在找到一个不存在的项目的上下接近应该是一块蛋糕。
Array.prototype.sortedFindIndex = function(val, cb = x => x) { // default callback for primitive arrays
var deli = this.length-1, // delta index
base = 0, // base to add the delta index
calculatedValue = cb(this[base + deli]), // use callback and get the value
expectedAt = i => { while (this[i] !== void 0 && cb(this[i]) < val) ++i;
return -i};
while (deli > 0 && calculatedValue != val) {
deli = ~~(deli/2);
(calculatedValue = cb(this[base + deli])) < val && (base += deli);
}
return calculatedValue === val ? base + deli : expectedAt(base + deli);
};
arr = [{a:0,b:"foo"},{a:1,b:"bar"},{a:2,b:"baz"},{a:3,b:"qux"},{a:4,b:"fox"},{a:5,b:"pun"},{a:6,b:"alf"},{a:7,b:"alf"},{a:8,b:"alf"},{a:9,b:"alf"},{a:10,b:"alf"},{a:11,b:"alf"},{a:13,b:"alf"}],
idx = arr.sortedFindIndex(12, o => o.a);
console.log(idx);