Christian
Christian

Reputation: 391

Ranking numbers in an array using JavaScript

Given an array of unique numbers, return a new array of rankings of the original array. For example, if your input array is [10, 5, 20], the output should be [2, 3, 1], since 10 is the second-largest number, 5 is the third largest, and 20 is the largest.

My answer is returning [1,2,0] rather than [2,3,1]. I can't figure where I'm going wrong?

function rankings(arr) {
  // add whatever parameters you deem necessary 
  var sorted = arr.slice().sort(function(a, b) {
    return b - a
  })
  var ranks = arr.slice().map(function(v) {
    return sorted.indexOf(v)
  });
  return ranks;
}

console.log(rankings([10, 5, 20]));

Upvotes: 3

Views: 7806

Answers (5)

Penny Liu
Penny Liu

Reputation: 17448

Gets much easier in ES6:

function rankings(arr) {
  const sorted = [...arr].sort((a, b) => b - a);
  return arr.map((x) => sorted.indexOf(x) + 1);
};

console.log(rankings([10, 5, 20]));

One more way to consider multiple duplicate entries.

function rankDuplicate(arr) {
  const sorted = [...new Set(arr)].sort((a, b) => b - a);
  const rank = new Map(sorted.map((x, i) => [x, i + 1]));
  return arr.map((x) => rank.get(x));
}

console.log(rankDuplicate([10, 10, 5, 20]));

Upvotes: 4

Nina Scholz
Nina Scholz

Reputation: 386660

You could

  • store the value along with the index in an array,
  • sort by value,
  • map the rank to the given value and index,
  • sort by index to get the original sorting of the array,
  • take the ranking.

function rankings(array) {
    return array
      .map((v, i) => [v, i])
      .sort((a, b) => b[0] - a[0])
      .map((a, i) => [...a, i + 1])
      .sort((a, b) => a[1] - b[1])
      .map(a => a[2]);
}

console.log(rankings([10, 5, 20])); // 2 3 1

Upvotes: 5

Sameer
Sameer

Reputation: 61

This is happening because arrays have index '0' as first element. change your code to this: var ranks = arr.slice().map(function(v){ return sorted.indexOf(v)+1});

Upvotes: 0

Paulo Candido
Paulo Candido

Reputation: 185

Try this out

function rankings(arr){
  // add whatever parameters you deem necessary....good luck! 
  var sorted = arr.slice().sort(function(a,b){return b-a})
  var ranks = arr.slice().map(function(v){ return sorted.indexOf(v) + 1});
  return ranks;
}

rankings([10, 5, 20]); // [2, 3, 1]

I just add 1 to the index which starts at 0

Upvotes: 2

User863
User863

Reputation: 20039

Array index starts from zero.

You can add the index with one

sorted.indexOf(v) + 1

function rankings(arr){
  // add whatever parameters you deem necessary....good luck! 
  var sorted = arr.slice().sort(function(a,b){return b-a})
  var ranks = arr.slice().map(function(v){ return sorted.indexOf(v) + 1 });
  return ranks;
}

console.log(rankings([10, 5, 20]));

Upvotes: 0

Related Questions