2

I am trying to find a way to get the max value of an array, then find all indexes of that value. I want to repeat this two more times.

I have an array of 8 scores. I want to find all first places, all second places, and all third places.

Array = [0, 400, 300, 400, 300, 200, 100, 200]

1st place indexes: 1, 3

2nd place indexes: 2, 4

3rd place indexes: 5, 7

How can I achieve this in javascript?

Blue Ice
  • 7,888
  • 6
  • 32
  • 52
Eric O
  • 23
  • 2
  • 1
    Where is the code that you need help with? – RobG Mar 09 '14 at 23:44
  • My guess: you're going to need a loop... – nnnnnn Mar 09 '14 at 23:45
  • Sorry, this is my first post. I thought this might be sufficient information. I have the array. I don't how to write the javascript to get what I'm looking for. – Eric O Mar 09 '14 at 23:46
  • 1
    http://stackoverflow.com/questions/1379553/how-might-i-find-the-largest-number-contained-in-a-javascript-array – Nicky Smits Mar 09 '14 at 23:46
  • 2
    The point RobG and I were making is that you don't seem to have made any attempt to code this on your own. [What have you tried?](http://mattgemmell.com/what-have-you-tried/) And in what format would you like the resulting indices? – nnnnnn Mar 09 '14 at 23:47

4 Answers4

2

The following code does the trick:

var scores = [0, 400, 300, 400, 300, 200, 100, 200];

// make a working copy, so that we can change the working copy
// while doing the calculations without changing the original array
var working = scores.slice(0),
    max,
    indices,
    numberOfPlaces = 3,
    results = []; 

for (var p = 0; p < numberOfPlaces; p++) {
    max = Math.max.apply(null, working);
    indices = [];
    for (var i = 0; i < working.length; i++)
        if (working[i] === max && working[i] > Number.NEGATIVE_INFINITY) {
            indices.push(i);
            working[i] = Number.NEGATIVE_INFINITY;
        }
    results.push(indices);
}

For your input results will be [[1,3], [2,4], [5,7]]. That is, results[0] will hold the first place indices, results[1] will hold the second place indices, and so on.

If you later decided you only wanted the first two places, or your wanted the first five, just change the numberOfPlaces variable.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • Thank you this makes a lot of sense. I will be trying this in my code. I will try to add more code in my future questions. – Eric O Mar 10 '14 at 00:10
1

Assuming the scores are not big numbers, you can build a hash of "score to indexes", and then sort by keys, and print out the indexes:

the running sample:

http://jsfiddle.net/nmA35/2/

the code:

var arr = [0, 400, 300, 400, 300, 200, 100, 200];
var hashValueToPosition = {};
var i;

for (i = 0; i < arr.length; i++) {
    hashValueToPosition[arr[i]] = (hashValueToPosition[arr[i]] || []);
    hashValueToPosition[arr[i]].push(i);
}

// see http://stackoverflow.com/questions/208016/how-to-list-the-properties-of-a-javascript-object  for Object.keys or the following:
var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}

var arrMaxToMinScores = getKeys(hashValueToPosition).sort().reverse();

for (i = 0; i < arrMaxToMinScores.length; i++) {
    $("body").append("<pre>" + arrMaxToMinScores[i] + ": " + JSON.stringify(hashValueToPosition[arrMaxToMinScores[i]]) + "</pre>");
}
nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • +1. I like this solution, but what do you mean by "Assuming the scores are not big numbers"? How big is too big? – nnnnnn Mar 10 '14 at 00:08
0
function awardPrizes(arr){
    var L= arr.length, prizes= [[], [], []], n;

    // save the three highest scores in scores array:
    // eg: [400,300,200]

    var scores= arr.slice().filter(function(n, i){
        return arr.indexOf(n)== i;
    }).sort(function(a, b){ return b-a}).slice(0, 3);

    //put the high scoring indexes in the relevant prizes array:

    arr.forEach(function(itm, i){
        n= scores.indexOf(itm);
        if(n!= -1) prizes[n].push(i);
    });
    return prizes;
    //[first group,second group,third group]

}
var data= awardPrizes([0, 400, 300, 400, 300, 200, 100, 200]);


/*  returned value: (Array)
[
    [1, 3],
    [2, 4],
    [5, 7]
]
    */
kennebec
  • 102,654
  • 32
  • 106
  • 127
0

Like functional programming?

a={};[0, 400, 300, 400, 300, 200, 100, 200].forEach(
    (el,i) => a[el]? a[el].push(i) : a[el]=[i]
);
Object.keys(a).sort().reverse().map(k => [Number(k),a[k].sort()])

Basically hashes all the values, then goes through the keys in descending order, mentioning the indexes in ascending order. Ex:

[
    [400,[1,3]],
    [300,[2,4]],
    [200,[5,7]],
    [100,[6]],
    [0,[0]]
]
AP.
  • 8,082
  • 2
  • 24
  • 33