开发者

Getting at javascript values where a range is the index in an array

I'm probably going about this in entirely the wrong way, but pseudocode-wise, this is what I'd like to do:

ranges = new Array([0 - 400] = 'dog',
               [401 - 1000] = 'cat',
               [1001 - 1233] = 'rat');

alert(ranges[243]);

and magically get 'dog' pop up on my screen. Now, I'm well aware you can't do 开发者_开发百科something that simple, but I have absolutely no idea how to do something like this (without looping through an array, performing a > and < on a value etc..)

Any ideas? :)


Well you could populate a simple array with all the duplicates:

var i,
    ranges = [];

for (i = 0; i <= 400; i++) ranges[i] = "dog";
for (i = 401; i <= 1000; i++) ranges[i] = "cat";
for (i = 1001; i <= 1233; i++) ranges[i] = "rat";

alert(ranges[243]); // "dog"

A more sensible option might be to use some kind of data structure that actually holds the low and high values of each range:

var ranges = [
  { "low" : 0, "high" : 400, "animal" : "dog" },
  { "low" : 401, "high" : 1000, "animal" : "cat" },
  { "low" : 1001, "high" : 1233, "animal" : "rat" }
];

function getAnimal(index) {
   for (var i=0; i < ranges.length; i++)
      if (ranges[i].low <= index && ranges[i].high >= index)
         return ranges[i].animal;

   return "Out of range"; // or could leave it to return undefined
}

alert(getAnimal(243)); // "dog"
alert(getAnimal(100000)); // "Out of range"

Or you could combine the two approaches: pass the ranges data structure with the low and high values to a function that uses the information to populate another array as per the first approach.


This one is very simple and straightforward - though it assumes that you don't want "holes" in your ranges. No error handling in this example, but essentially you just need to pass upper bounds, lower bounds are implicit.

function test() {
    var array = MakeRangeArray([500,1000,2000], ['dog', 'cat', 'rat']);

    alert (array[243]);
    alert (array[500]);
    alert (array[501]);
}

function MakeRangeArray(upperBounds, values) {
   var rangeArray = new Array(upperBounds[upperBounds.length-1]);

   var idx = 0;
   for (var i=0; i < rangeArray.length; i++) {
      if (i > upperBounds[idx]) {
        idx++;
      }
      rangeArray[i] = values[idx];
   }
   return rangeArray;
}


You could fully populate an array sp you can dp a direct index into the array at run-time. Once the original data structure is created, that will be fast at run-time, but not very storage efficient. I generally wouldn't recommend this, but to build the array:

var ranges = [
    {min: 0, max: 400, value: 'dog'},
    {min: 401, max: 1000, value: 'cat'},
    {min: 1001, max: 1233, value: 'rat'}
];

var lookupArray = [];
for (var i = 0; i < ranges.length; i++) {
    // make sure array is big enough
    lookupArray.length = Math.max(lookupArray.length, ranges[i].max);
    for (var j = ranges[i].min, j <= ranges[i].max; j++) {
        lookupArray[j] = ranges[i].value;
    }
}

// function to find the value for a given index
function findValue(index) {
    return(lookupArray[index]);
}

Or, in a more compact structure, you can use a data structure and function like this:

var ranges = [
    {min: 0, max: 400, value: 'dog'},
    {min: 401, max: 1000, value: 'cat'},
    {min: 1001, max: 1233, value: 'rat'}
];

function findValue(index) {
    var range;
    for (var i = 0; i < ranges.length; i++) {
        range = ranges[i];
        if (index >= range.min && index <= range.max) {
            return(range.value);
        }
    }
}

alert(findValue(402));    // 'cat'

You could also use a straight array with implicit positions in the array (code and data are a little more compact, but both are a bit less readable):

var ranges = [
    0, 400, 'dog',
    401, 1000, 'cat',
    1001, 1233, 'rat'
];

function findValue(index) {
    for (var i = 0; i < ranges.length; i+=3) {
        if (index >= ranges[i] && index <= ranges[i+1]) {
            return(ranges[i+2];
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜