2

I have a long list of number ranges between 0 and 1000000, each correlating to another number.

It's for an HTML form to calculate prices. I thought about using a set of arrays or an if-else chain, but I'm looking for the most efficient way to accomplish the same task.

Here's a sample:

Range Result
0 - 40000 2000
40001-50000 2500
50001-60000 3000

I'd like to be able to provide the script a number, such as 45000 and have it return 2500 as the result. How can I do this without creating a long if-else chain?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
Gene
  • 31
  • 3
  • 1
    Make an array [0,40000,50000,60000]. You can do a binary search to find out between which two items some candidate number falls. It may be less than the first element or greater than the last element. Beware off-by-one errors and inclusive vs exclusive range values, (e.g. where does 40000.5 belong?) but other than that, it's a straightforward binary search. – Wyck Dec 12 '22 at 17:22
  • 1
    Does this answer your question? [Check if a value is within a range of numbers](https://stackoverflow.com/questions/6454198/check-if-a-value-is-within-a-range-of-numbers) – Heretic Monkey Dec 12 '22 at 17:33
  • @HereticMonkey this question is about techniques for finding which one of _multiple ranges_ an input falls within- not whether an input is within an single range. – starball Dec 16 '22 at 01:50
  • @starball It's called a loop, one of the primary methods of iterating over data. If the user has never heard of that, then they're hardly in the "professional and enthusiast programmer" group this site is meant for. – Heretic Monkey Dec 16 '22 at 23:33
  • Think how you want and express your thoughts how you want (in a way that works with the CoC) I'm disagreeing speciically with the dup target. See ["_When are two questions considered duplicates?_"](https://meta.stackexchange.com/a/10844/997587). I understand this question to be a different question than the dup target you proposed. It would be appropriate to write an answer that explains how to combine usage of a loop with that post you linked. You are within your rights to vote how you wish as long as it is not fraudulent. But I'm not sure about this dup target. – starball Dec 16 '22 at 23:36

2 Answers2

1

This code will return undefined if no ranges match. The lower end of the range is inclusive, the upper end exclusive.

const ranges = [
  {start:0,     end: 40000, val:2000},
  {start:40000, end: 50000, val:2500},
  {start:50000, end: 60000, val:3000}
]
function f(n) { 
  return ranges.find(({start,end}) => n>=start && n<end)?.val
}
console.log(f(45000))
Andrew Parks
  • 6,358
  • 2
  • 12
  • 27
  • That puts 40000 in the wrong bin. – Wyck Dec 12 '22 at 17:24
  • Your `end` of one Object is the `start` of the next object, which isn't what OP wrote (minor typo, not downvoting); but also, please take the time to explain how the code works so that Gene - and others - can learn from it. – David Thomas Dec 12 '22 at 17:26
  • @DavidThomas The questioner will probably realise that there is an ambiguity when the number being tested is between 40000 and 40001 (thanks to Wyck's comment on the original question). I've therefore specified that the upper end is exclusive, and the OP is free to specify exactly where the ranges really should be. – Andrew Parks Dec 12 '22 at 17:28
1

Perhaps looping through objects of that table?

Below, I've used the for...of syntax of newer ECMAScript

const values = [
  {lower: 0, upper: 40000, result: 2000},
  {lower: 40001, upper: 50000, result: 2500},
  {lower: 50001, upper: 60000, result: 3000}
]


// ES for...of loop
const getValue = (value) => {
  let result = undefined;
  for (const v of values) {
    if (value >= v.lower && v.upper >= value) {
      result = v.result;
      break;
    }
  }
  return result
}

console.log(getValue(45000))
starball
  • 20,030
  • 7
  • 43
  • 238
Harrison
  • 1,654
  • 6
  • 11
  • 19