Reputation: 753
I have an array like this:
[{
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 6.4
}
}, {
"number": "3",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}, {
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}]
I am trying to create a new array with the following criteria:
array.rating.average
) of each number (array.number
)Output should be:
[{
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 6.4
}
}, {
"number": "3",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}
}]
I have just managed to sort by highest rating:
array.sort(function(a , b) {
return a.rating.average - b.rating.average;
});
array.reverse();
But, now, I just only want one object per duplicate array.number
, keeping the one that has the highest array.rating.average
.
Upvotes: 9
Views: 84741
Reputation: 171
Simply you can use lodash method for sort by anything that you want to sort by fileName, number, etc.
const _ = require('lodash');
var data = [{
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 6.4
}
}, {
"number": "3",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}, {
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}]
var result = _.sortBy(data, ['number']);
console.log(result)
Output:
[ { number: '3', fileName: 'fileXX', rating: { average: 5.4 } },
{ number: '4', fileName: 'fileXX', rating: { average: 6.4 } },
{ number: '4', fileName: 'fileXX', rating: { average: 5.4 } } ]
Upvotes: 0
Reputation: 3406
arr = [{
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 6.4
}
}, {
"number": "3",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}, {
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}]
arr = arr.sort(function(a,b){return b.number-a.number || b.rating.average-a.rating.average}).filter(function(a,b,c){return !b || c[b-1].number != a.number});
console.log(arr);
I believe that this will solve your problem by sorting and filtering.
EDIT: Should now support older browsers.
Upvotes: 0
Reputation: 10897
array.sort((a, b) => {
if(a.number === b.number) {
// If two elements have same number, then the one who has larger rating.average wins
return b.rating.average - a.rating.average;
} else {
// If two elements have different number, then the one who has larger number wins
return b.number - a.number;
}
});
array = array.filter((element, index) => {
return index === 0 || element.number !== array[index-1].number;
});
For your test case,
[{
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 6.4
}
}, {
"number": "3",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}, {
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}]
After sorting, the output would be
[{
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 6.4
}
}, {
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}, {
"number": "3",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}]
And after filter, the final result:
[{
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 6.4
}
}, {
"number": "3",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}]
Upvotes: 13
Reputation: 6169
First you create a dictionary for keeping the highest rating for each number:
var data = [{
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 6.4
}
}, {
"number": "3",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}, {
"number": "4",
"fileName": "fileXX",
"rating": {
"average": 5.4
}
}];
var filterMap = {};
data.forEach(function (item) {
if (!filterMap[item.number] || filterMap[item.number].rating.average < item.rating.average) {
filterMap[item.number] = item;
}
})
var result = [];
for (var number in filterMap) {
result.push(filterMap[number]);
}
result.sort(function(a , b) {
return b.rating.average - a.rating.average;
});
console.log(result);
Upvotes: 1