Percentile for a value

Given an array of numbers, I am looking to find the percentile of a given value.

I found this code here that seems to do what I need, but I was hoping I could get someone to explain this code to me step by step:

const percentile = (arr, val) =>
  (100 *
    arr.reduce(
      (acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0),
      0
    )) /
  arr.length;

// example
// percentile([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6); // 55

Update

Thanks everyone for your help. I found a Percentile formula that further helps me understand what the code is doing.

Formula:

Percentile = [L + ( 0.5 x S ) / N] * 100

  • L = Number of below rank
  • S = Number of same rank
  • N = Total numbers

Based on my new understanding of the function, I find this a bit easier to read:

/**
 * **Percentile = ((L + ( 0.5 x S )) / N) * 100**
 * - L = Number of values **lower** than `value`
 * - S = Number of same rank
 * - N = Total numbers
 */
const percentile = (arr, value) => {
  const currentIndex = 0;
  const totalCount = arr.reduce((count, currentValue) => {
    if (currentValue < value) {
      return count + 1; // add 1 to `count`
    } else if (currentValue === value) {
      return count + 0.5; // add 0.5 to `count`
    }
    return count + 0;
  }, currentIndex);
  return (totalCount * 100) / arr.length;
};

Answer

The function is equivalent to ths simpler version.

count contains the number of elements that val is higher than, plus 0.5 for each element it’s equal to. Dividing this total by the number of elements is the percentile.

const percentile = (arr, val) => {
  let count = 0;
  arr.forEach(v => {
    if (v < val) {
      count++;
    } else if (v == val) {
      count += 0.5;
    }
  });
  return 100 * count / arr.length;
}

console.log(percentile([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6));