-1

I have below array

const floorPerDayMilestones = [25, 50, 75, 100, 125, 150, 175, 200]

From the frontEnd user enters any number say it is

const number = 136

I need to find closest to the number but the lesser one. So the output should be 125

Even if the number is 149 the output should be 125

How can I do this. I tried many way but could get the answer.

Thanks!!!

Profer
  • 553
  • 8
  • 40
  • 81

7 Answers7

1

You can use Array.reduce for this

const floorPerDayMilestones = [25, 50, 75, 100, 125, 150, 175, 200]

function getClosestNumber(d) {
  return floorPerDayMilestones.reduce((a, b) => b <=d && a < b ? b : a, 0 )
}

console.log(getClosestNumber(135) || 'No lesser number available')

console.log(getClosestNumber(149) || 'No lesser number available')

console.log(getClosestNumber(22) || 'No lesser number available')
Nitish Narang
  • 4,124
  • 2
  • 15
  • 22
1

Maybe you should look at this: get closest number out of array

And in your foreach, save your closest number in a var. Then check if your number is bigger than the one in your array . if yes, take your last var, else continue your foreach

1

Try this

const floorPerDayMilestones = [25, 50, 75, 100, 125, 150, 175, 200];
    
const number = 136;
    
    
const nextLesser = floorPerDayMilestones.reduce((nl, curr) => (curr <= number) && (curr > nl) ? curr : nl , 0)

console.log(nextLesser)

Used Array.prototype.reduce

Nurbol Alpysbayev
  • 19,522
  • 3
  • 54
  • 89
1

You can sort the array in ascending order and then find the index of number that is immediately higher than number then one position less of that value will be the immediate number that is less than number

const floorPerDayMilestones = [25, 50, 75, 100, 125, 150, 175, 200]
const number = 136;
floorPerDayMilestones.sort((a,b)=> a-b);
var index = floorPerDayMilestones.findIndex(val => val>number);
var num = floorPerDayMilestones[index-1];
console.log(num);
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62
1

You can also filter out numbers greater than given and select max from this subset.

const floorPerDayMilestones = [25, 50, 75, 100, 125, 150, 175, 200]

const number = 136

const filtered = floorPerDayMilestones.filter(el=>el<=number);

console.log(Math.max(...filtered))

Or, if you're already using lodash (only in this case - don't import lodash just to use solution below), you can do it with maxBy. maxBy treats numbers greater than number as null.

const floorPerDayMilestones = [25, 50, 75, 100, 125, 150, 175, 200]

const number = 136

let result = _.maxBy(floorPerDayMilestones, el=>el<=number?el:null);

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
barbsan
  • 3,418
  • 11
  • 21
  • 28
1

With lodash you could use _.sortedIndex:

const numbers = [25, 50, 75, 100, 125, 150, 175, 200]

const closestNum = (arr, n) => {
  let index = _.sortedIndex(arr, n)
  return arr[index] == n ? arr[index] : arr[index-1]
}

console.log(closestNum(numbers, 135))  // 120
console.log(closestNum(numbers, 160))  // 150
console.log(closestNum(numbers, 180))  // 175
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

With JS you can simply use Array.reduceRight:

const numbers = [25, 50, 75, 100, 125, 150, 175, 200]

const closestNum = (arr, n) => arr.reduceRight((r,c) => !r && c < n ? c : r, 0)

console.log(closestNum(numbers, 135))  // 120
console.log(closestNum(numbers, 160))  // 150
console.log(closestNum(numbers, 180))  // 175

Since it will start from the right side all you care about is to find the first number less than your argument n.

You could also do Array.reverse and then just Array.filter (use Array.from if you do not want to mutate the array):

const numbers = [25, 50, 75, 100, 125, 150, 175, 200]

const closestNum = (arr, n) => arr.reverse().find(x => x < n)

// To not mutate use `Array.from`
// const closestNum = (arr, n) => Array.from(arr).reverse().find(x => x < n)

console.log(closestNum(numbers, 135))  // 120
console.log(closestNum(numbers, 160))  // 150
console.log(closestNum(numbers, 180))  // 175
Akrion
  • 18,117
  • 1
  • 34
  • 54
0

If it's sorted in ascending order like in the question this should work.

const floorPerDayMilestones = [25, 50, 75, 100, 125, 150, 175, 200];
const number = 136;

function findClosest(arr, num) {
  for (let i = 0; i < arr.length; ++i) {
    if (arr[i] > num) {
      return arr[i - 1];
    }
  }
}

console.log(findClosest(floorPerDayMilestones,number));
lloydaf
  • 605
  • 3
  • 17