给定一个存储为 [{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 我想确定它的位置。所以如果:

我在 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