使用Javascript查找范围值的索引

Find index on ranged values using Javascript

本文关键字:索引 范围 Javascript 查找 使用      更新时间:2023-09-26

给定以下范围和索引:

index   from        to
11      24          48
10      12          24
9       6           12
8       3           6
7       1.5         3
6       0.75        1.5
5       0.375       0.75
4       0.1875      0.375
3       0.09375     0.1875
2       0.046875    0.09375
1       0.0234375   0.046875
0       0.015625    0.0234375

我应该如何组织这个(数据/算法)以获得类似于的东西

x=0.22;
n=findIndex(x);
alert(n);
// output 4

显然,它可以适用于任何大小的索引。我脑子里唯一想的是嵌套的如果。。。

thx。

我会写这样的东西:

var indexes = {
  11 : [24, 48], 
  10 : [12, 24],
  9 : [6, 12],
  8 : [3, 6],
  7 : [1.5, 3],
  6 : [0.75, 1.5],
  5 : [0.375, 0.75],
  4 : [0.1875, 0.375],
  3 : [0.09375, 0.1875],
  2 : [0.046875, 0.09375],
  1 : [0.0234375, 0.046875],
  0 : [0.015625, 0.0234375]
};
var x = 0.22;
var n = findIndex(x);
function findIndex(d){
    for(var key in indexes){
    if(d >= indexes[key][0] && d <= indexes[key][1]) 
      return key;
     }
}
alert(n);

Fiddle

可能不是最高效的代码,乐于改进。

使用二进制搜索对索引范围进行搜索,并检查该点是否在给定索引的范围内或任一侧。

既然数组看起来是排序的,为什么不使用二进制搜索算法呢。我使用二进制搜索和匹配条件组合了一个jsfiddle,假设包含"from"。换句话说,6将匹配9而不是8。

ranges = [
    {from: .015625, to: .0234375},
    {from: .0234375, to: .046875},
    {from: .046875, to: .09375},
    {from: .09375, to: .1875},
    {from: .1875, to: .375},
    {from: .375, to: .75},
    {from: .75, to: 1.5},
    {from: 1.5, to: 3},
    {from: 3, to: 6},
    {from: 6, to: 12},
    {from: 12, to: 24},
    {from: 24, to: 48}
];

//A function that can build an array of ranges
//by doubling the seed... This looks to produce a
//different results than your ranges as 
// .0234375 is not twice .015625.
var buildRanges = function (seed, maxIndex) {
    var tmp = [];
    var curr = 0;
    var from = seed;
    var to = 2 * from;
    while (curr <= maxIndex) {
        tmp.push({from: from, to: to});
        from = to;
        to = 2 * from;
        curr++;
    }
    return tmp;
}
var findIndex = function (x) {
    var min = 0;
    var max = ranges.length - 1
    var mid;
    while (min <= max) {
        mid = parseInt((max + min) / 2);
        //Assume "from" field is inclusive
        if (x >= ranges[mid].from && x < ranges[mid].to) {
            return mid;
        }
        //We know that maximum must be adjusted below mid
        else if (x < ranges[mid].from) {
            max = mid - 1;
        }
        //Else we must move up the min
        else {
            min = mid + 1;
        }
    }
}
alert(findIndex(.22)); //4
alert(findIndex(6)); //9
alert(findIndex(12)); //10
alert(findIndex(.9)); //6