给定存储为[{name,value},...]的间隔,我如何找到x所在的位置?

时间:2015-01-12 05:18:11

标签: javascript intervals

为了便于说明这个例子,我有一个像这样的间隔:

        -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,它将返回normal
  • x = 6 or 100,它将返回good
  • x = -1 or 1 or -2,它将返回''(因为没有分配给这些间隔)
  • 和负数类似

我在js中的实现是循环遍历每个对象,如果它是>=,它将覆盖。但是我会再次为负面编写相同的代码,但使用<=,是否有人有更好的实现?

var x = 4;
var returnInterval = '';
for (var point in interval) {
   if (x >= interval[point].value) {
       returnInterval = interval[point].name;
   }
}

return returnInterval;

2 个答案:

答案 0 :(得分:3)

考虑定义这样的范围:

[
  { 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 '';
}

支票是否为&gt; =,&gt;,&lt;&lt;或者&lt; =取决于你。

答案 1 :(得分:1)

这适合您的数据结构,但似乎有点脆弱。它只是应用不同的逻辑,取决于值所在的中心的哪一侧。它可以应用于任何大小范围的数据数组,只要它具有偶数个成员。

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