-1

I would find the 3 largest values ​​of an object array in javascript.

Here is my array of objects :

data = [
{"name" : "Ariana" , "score" : "130"},
{"name" : "Iggy" , "score" : "270"},
{"name" : "Aron" , "score" : "30"},
{"name" : "Josh" , "score" : "20"},
{"name" : "Kevin" , "score" : "10"},
{"name" : "John" , "score" : "80"},
{"name" : "Nicky" , "score" : "45"}]

The array who i search :

dataTop3 = [
{"name" : "Ariana" , "score" : "130"},
{"name" : "Iggy" , "score" : "270"},
{"name" : "John" , "score" : "80"}]

I just managed to find the bigger one with this code :

function value_max(data){
    var max=0;
    for (i in data) if(data[i]>max) max=data[i];
    return max;
}
max=value_max(data);
Cœur
  • 37,241
  • 25
  • 195
  • 267
Mike Tilam
  • 105
  • 9

4 Answers4

2

In your solution you are replacing the value in max in each iteration based on the condition, which in the end will give you only one value, you will need to use an array to return more than one value.

A solution would be to just sort the entire array, using a comparator function to compare score key in each object, and then use top k values as you need.

var data = [
{"name" : "Ariana" , "score" : "130"},
{"name" : "Iggy" , "score" : "270"},
{"name" : "Aron" , "score" : "30"},
{"name" : "Josh" , "score" : "20"},
{"name" : "Kevin" , "score" : "10"},
{"name" : "John" , "score" : "80"},
{"name" : "Nicky" , "score" : "45"}];


data.sort((x,y) => y.score-x.score);

console.log(data.splice(0,3));

Another solution would be to maintain an array of size 4 and sort it on each iteration and add next element at last position.

var data = [
{"name" : "Ariana" , "score" : "130"},
{"name" : "Iggy" , "score" : "270"},
{"name" : "Aron" , "score" : "30"},
{"name" : "Josh" , "score" : "20"},
{"name" : "Kevin" , "score" : "10"},
{"name" : "John" , "score" : "80"},
{"name" : "Nicky" , "score" : "45"}];

function value_max(data){
var max=0, vals = [];
for (i in data) {
    if(vals.length === 4){
        vals.sort((x,y) => y.score-x.score);
        vals[3] = data[i]
    }else{
        vals.push(data[i]);
    }
}
vals.sort().pop();
return vals;
}
max=value_max(data);
console.log(max);
Dij
  • 9,761
  • 4
  • 18
  • 35
1

You could sort a copy of the array and slice the top items.

var data = [{ name: "Ariana", score: "130" }, { name: "Iggy", score: "270" }, { name: "Aron", score: "30" }, { name: "Josh", score: "20" }, { name: "Kevin", score: "10" }, { name: "John", score: "80" }, { name: "Nicky", score: "45" }],
    top3 = data
        .slice()
        .sort(function (a, b) { return b.score - a.score; })
        .slice(0, 3);
    
console.log(top3);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • You went above and beyond, not only is your solution the fastest, but you also don't mutate the original. However, why did you use a return instead of a fat arrow for your sort? – Rick Sep 19 '17 at 16:01
  • @Rick, because the question is not tagged as ES6, but can replace the sort part with `.sort((a, b) => b.score - a.score)`, if you like. – Nina Scholz Sep 19 '17 at 16:04
  • no, it's fine, I didn't notice the absence of an es6 tag. Good job, skillz. – Rick Sep 19 '17 at 16:10
0

If I understand your question correctly, you could first sort the array, based on the score, using the following sort-function:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Then, you can easily get the first or last three items, depends if you sort highest first or lowest first. So if you sort highest first:

sortedArray[0], sortedArray[1], sortedArray[2]

Erwin Okken
  • 233
  • 2
  • 17
0

Have you tried something like this?

while ( data.length > 3) {
    if (data[3] > data[2]) {
        data.splice(2,1);
    } else if (data[3] > data[1]) {
        data.splice(1,1);
    } else if (data[3] > data[0]) {
        data.splice(0,1);
    } else {
        data.splice(3,1);
    }
}
dataTop3 = data;