Reputation: 23
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?
Upvotes: 2
Views: 273
Reputation: 8931
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]]
]
Upvotes: 0
Reputation: 104840
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]
]
*/
Upvotes: 0
Reputation: 151234
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:
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>");
}
Upvotes: 1
Reputation: 150080
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.
Upvotes: 2