给定一个存储为 [{name, value},...] 的区间,我如何找到 x 所在的位置?
Given an interval stored as [{name, value},...], how would I find where x lies?
为了方便说明这个例子,我有一个这样的区间:
-6 -3 0 3 6
<-------o---------o---------o---------o--------o------->
danger| warning | | normal | good
我将其存储为一个对象,(-3 到 3 之间没有任何注意)
编辑:这是我得到的数据结构,无法进行任何更改。
{ name: 'good', value: 6 },
{ name: 'normal', value: 3 },
{ name: 'warning', value: -3 },
{ name: 'danger', value: -6 },
给定一个值 x
我想确定它的位置。所以如果:
x = 3 or 4
,会returnnormal
x = 6 or 100
,会returngood
x = -1 or 1 or -2
,它将 return ''(因为没有为这些间隔分配任何内容)
- 负数也是如此
我在 js 中的实现是循环遍历每个对象,如果是 >=
,它会覆盖。但我会再次为底片编写相同的代码,但使用 <=
,有没有人有更好的实现?
var x = 4;
var returnInterval = '';
for (var point in interval) {
if (x >= interval[point].value) {
returnInterval = interval[point].name;
}
}
return returnInterval;
考虑像这样定义您的范围:
[
{ name: 'good', range: [6, Infinity },
{ name: 'normal', range: [3, 6] },
{ name: 'warning', value: [-6, -3] },
{ name: 'danger', value: [-Infinity, -6] }
]
利用现有数据,您可以构建这样一个范围:
var points = [
{ name: 'danger', value: -6 },
{ name: 'warning', value: -3 },
{ name: 'normal', value: 3 },
{ name: 'good', value: 6 }
];
// PRE CONDITION: elements are sorted by value (ascending)
var prev = -Infinity;
for (i = 0, j = 0; i <= points.length; ++i) {
var current = i == points.length ? Infinity : points[i].value;
if (prev >= 0 || current <= 0) {
points[j].range = [prev, current];
++j;
}
prev = current;
}
它基本上跳过具有负开始和正结束值的段。
然后,您可以对每个区域进行简单的边界检查。
function name(value)
{
for (var i = 0; i != points.length; ++i) {
var range = points[i].range;
if (value >= range[0] && value <= range[1]) {
return points[i].name;
}
}
return '';
}
检查的具体细节是 >=、>、< 还是 <= 由您决定。
这符合你的数据结构,但它似乎有点脆弱。它只是根据值位于中心的哪一侧应用不同的逻辑。它可以应用于任何大小范围的数据数组,只要它具有偶数个成员。
var rangeData = [
{ name: 'good', value: 6 },
{ name: 'normal', value: 3 },
{ name: 'warning', value: -3 },
{ name: 'danger', value: -6 }
];
function getRangeName(rangeData, value) {
// Get the middle range index, assume length is always even
var midRange = rangeData.length / 2 - 1;
var v, next;
for (var i=0, iLen=rangeData.length; i<iLen; i++) {
v = rangeData[i].value;
next = rangeData[i+1]? rangeData[i+1].value : -Infinity;
// High side of middle
if (i <= midRange && value >= v ) {
return rangeData[i].name;
// Low side of middle
} else if (i > midRange && value <= v && value > next) {
return rangeData[i].name;
}
}
// Default if in middle
return '';
}
var testData = [7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7];
testData.forEach(function(v) {
console.log(v + ': ' + getRangeName(rangeData, v));
});
结果:
7: good
6: good
5: normal
4: normal
3: normal
2:
1:
0:
-1:
-2:
-3: warning
-4: warning
-5: warning
-6: danger
-7: danger
为了方便说明这个例子,我有一个这样的区间:
-6 -3 0 3 6
<-------o---------o---------o---------o--------o------->
danger| warning | | normal | good
我将其存储为一个对象,(-3 到 3 之间没有任何注意)
编辑:这是我得到的数据结构,无法进行任何更改。
{ name: 'good', value: 6 },
{ name: 'normal', value: 3 },
{ name: 'warning', value: -3 },
{ name: 'danger', value: -6 },
给定一个值 x
我想确定它的位置。所以如果:
x = 3 or 4
,会returnnormal
x = 6 or 100
,会returngood
x = -1 or 1 or -2
,它将 return ''(因为没有为这些间隔分配任何内容)- 负数也是如此
我在 js 中的实现是循环遍历每个对象,如果是 >=
,它会覆盖。但我会再次为底片编写相同的代码,但使用 <=
,有没有人有更好的实现?
var x = 4;
var returnInterval = '';
for (var point in interval) {
if (x >= interval[point].value) {
returnInterval = interval[point].name;
}
}
return returnInterval;
考虑像这样定义您的范围:
[
{ name: 'good', range: [6, Infinity },
{ name: 'normal', range: [3, 6] },
{ name: 'warning', value: [-6, -3] },
{ name: 'danger', value: [-Infinity, -6] }
]
利用现有数据,您可以构建这样一个范围:
var points = [
{ name: 'danger', value: -6 },
{ name: 'warning', value: -3 },
{ name: 'normal', value: 3 },
{ name: 'good', value: 6 }
];
// PRE CONDITION: elements are sorted by value (ascending)
var prev = -Infinity;
for (i = 0, j = 0; i <= points.length; ++i) {
var current = i == points.length ? Infinity : points[i].value;
if (prev >= 0 || current <= 0) {
points[j].range = [prev, current];
++j;
}
prev = current;
}
它基本上跳过具有负开始和正结束值的段。
然后,您可以对每个区域进行简单的边界检查。
function name(value)
{
for (var i = 0; i != points.length; ++i) {
var range = points[i].range;
if (value >= range[0] && value <= range[1]) {
return points[i].name;
}
}
return '';
}
检查的具体细节是 >=、>、< 还是 <= 由您决定。
这符合你的数据结构,但它似乎有点脆弱。它只是根据值位于中心的哪一侧应用不同的逻辑。它可以应用于任何大小范围的数据数组,只要它具有偶数个成员。
var rangeData = [
{ name: 'good', value: 6 },
{ name: 'normal', value: 3 },
{ name: 'warning', value: -3 },
{ name: 'danger', value: -6 }
];
function getRangeName(rangeData, value) {
// Get the middle range index, assume length is always even
var midRange = rangeData.length / 2 - 1;
var v, next;
for (var i=0, iLen=rangeData.length; i<iLen; i++) {
v = rangeData[i].value;
next = rangeData[i+1]? rangeData[i+1].value : -Infinity;
// High side of middle
if (i <= midRange && value >= v ) {
return rangeData[i].name;
// Low side of middle
} else if (i > midRange && value <= v && value > next) {
return rangeData[i].name;
}
}
// Default if in middle
return '';
}
var testData = [7,6,5,4,3,2,1,0,-1,-2,-3,-4,-5,-6,-7];
testData.forEach(function(v) {
console.log(v + ': ' + getRangeName(rangeData, v));
});
结果:
7: good
6: good
5: normal
4: normal
3: normal
2:
1:
0:
-1:
-2:
-3: warning
-4: warning
-5: warning
-6: danger
-7: danger