是否有一种比执行此操作更快的方法:
var value = 2432;
if (value >= 20 && value <= 31) return true;
else if (value >= 45 && value <= 47) return true;
else if (value >= 82 && value <= 86) return true;
...
else if (value >= 1052 && value <= 1065) return true;
else if (value >= 2400 && value <= 2500) return true;
条件语句包含不在模式中的数字。这个数字高达65,000。同样,范围是可变的并且彼此不相交。范围存储在SQL数据库中:
columns: from, to
rows: [21, 59], [92, 280], etc...
我最初是想创建一个查找表,其中包含范围之间的所有数字(例如[20, 21, 21, 23, ... 31, -> 45, 46 47]
)。
有更好的方法吗?
答案 0 :(得分:4)
因此,如果范围是唯一的并且彼此不相交。 我认为下一个算法是最快的检查方法:
start
值如果排序是在数据库端进行的,则该算法将是足够快的O(logN)。
答案 1 :(得分:3)
您可以制作一个[start, end]
数组的数组:
const ranges = [
[20, 31],
[45, 47],
[82, 86],
// …
[1052, 1065],
[2400, 2500]
];
然后使用Array.prototype.find
或Array.prototype.some
查找value
所在的范围(例如let value = 2432;
):
ranges.find(([start, end]) => value >= start && value <= end); // Returns `[2400, 2500]`, which is the range the value is in, or
!!ranges.find(([start, end]) => value >= start && value <= end); // Returns `true`, since the value is in a range, or
ranges.some(([start, end]) => value >= start && value <= end); // Returns `true`, since the value is in a range, or
答案 2 :(得分:0)
如果您可以在sql中进行查询并且没有交集,则仅具有一个表,其所有可能的值在1到65000之间,并且如果数字对索引有效,则具有bool列。您只会对更新性能产生重大影响。 在这种情况下,请执行以下操作:
Value isRange
1 true
SELECT * FROM RangeTable,其中Value = @Value和isRange = true
这为阅读进行了优化,但是,如果您经常更新,则无济于事。
您是否经常更新?
答案 3 :(得分:0)
您当然可以减少必须编写的条件语句的数量。
假设您的“从-到”数组以[ [n1, n2], [n3, n4], ... ]
的形式从服务器到达,则一旦有匹配项,就可以循环遍历每个范围和return
,或者返回false否则:
let ranges = [ [20, 31], [45, 47] ];
let valueInRange = 46;
let valueNotInRange = 33;
function isValInRange(value, rangeArr) {
for(let i = 0; i < rangeArr.length; i++) {
if(value >= rangeArr[0] && value <= rangeArr[1]) {
return true;
}
return false;
}
console.log(isValInRange(valueInRange, ranges)); //true
console.log(isValInRange(valueNotInRange, ranges)); //false
答案 4 :(得分:0)
如果要比对这些值进行更多地检查,则一种选择是构造具有范围的树,并搜索它比遍历所有选项快一点。不过,您可能希望使树保持平衡,否则不会对您有多大帮助。
/*
Construct this dynamically
min: range minimum
max: range maximum
lt: node for ranges less than this range
gt: node for ranges greater than this range
I'd probably make a class for this.
*/
const ranges = {
min: 82,
max: 86,
lt: {
min: 45,
max: 47,
lt: {
min: 20,
max: 31
}
},
gt: {
min: 2400,
max: 2500,
lt: {
min: 1052,
max: 1065
}
}
};
function lookup(value) {
let current = ranges;
while (current) {
if (value < current.min) {
current = current.lt;
} else if (value > current.max) {
current = current.gt;
} else {
return true;
}
}
return false;
}
这实际上是为值做的: