3

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? :)

2
  • 1
    You could write your own prototype for that which handles multiple arrays itself and hides this away from the user. (user meant as the dev who uses your stuff)
    – Peter
    Commented Sep 28, 2011 at 6:57
  • Not a poor example at all, i totally misread :)
    – amosrivera
    Commented Sep 28, 2011 at 6:58

3 Answers 3

3

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.

2

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;
}
4
  • All really good answers, but I had to give this one the tick as it's what I needed (don't need 'holes'!) I did mod up all others, thanks guys.
    – John Hunt
    Commented Sep 28, 2011 at 22:57
  • My ranges actually go up into the millions, is this a waste of memory doing it this way? Will it slow/mess up old browsers/old computers?
    – John Hunt
    Commented Sep 28, 2011 at 23:25
  • Well, 50,000 but could go into the millions in the future
    – John Hunt
    Commented Sep 29, 2011 at 0:06
  • Yes, if your array size goes up into the millions, this is probably a spectacularly bad idea; especially if your internal ranges are large. What you might do is create a custom 'class' that incorporates the logic from the answer by @jfriend000.
    – dividius
    Commented Sep 29, 2011 at 13:42
2

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];
        }
    }
}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.