How can I remove an object from array of objects based on max value in javascript
How can I remove an object from array of objects based on max value in javascript
I've got an array of objects that looks like this:
[ { person: 'Fred', scoreTotal: 29 },
{ person: 'Alice', scoreTotal: 34 },
{ person: 'Alice', scoreTotal: 22 },
{ person: 'Mary', scoreTotal: 14 },
{ person: 'Bob', scoreTotal: 33 },
{ person: 'Bob', scoreTotal: 13 },
{ person: 'Bob', scoreTotal: 22 },
{ person: 'Joe', scoreTotal: 28 }]
and where there are multiple objects for a given person -> I want to keep the top "X". For example:
a. top 1 result for a person
Result would look like this:
[ { person: 'Fred', scoreTotal: 29 },
{ person: 'Alice', scoreTotal: 34 },
{ person: 'Mary', scoreTotal: 14 },
{ person: 'Bob', scoreTotal: 33 },
{ person: 'Joe', scoreTotal: 28 }]
b. top 2 results for a person
Result would look like this:
[ { person: 'Fred', scoreTotal: 29 },
{ person: 'Alice', scoreTotal: 34 },
{ person: 'Alice', scoreTotal: 22 },
{ person: 'Mary', scoreTotal: 14 },
{ person: 'Bob', scoreTotal: 33 },
{ person: 'Bob', scoreTotal: 22 },
{ person: 'Joe', scoreTotal: 28 }]
Is there a way to achieve this using something like Lodash?
I think I'm heading in the right direction with this but not quite there yet:
for (var i = 0; i < t.length - 1; i++) {
if (
t[i].golfer === t[i + 1].golfer &&
t[i].scoreTotal < t[i + 1].scoreTotal
) {
delete t[i];
}
}
// remove the "undefined entries"
t = t.filter(function(el) {
return typeof el !== "undefined";
});
console.log(t);
3 Answers
3
Here is a solution with lodash...
function pickTopX(data, x) {
let grouped = _.groupBy(data, 'person');
let sorted = _.sortBy(grouped, 'scoreTotal');
let sliced = _.map(sorted, function(pair) {
return _.take(pair, x)
});
let result = _.flatten(sliced);
return result;
}
This isn't a full answer, just a tip. Don't use delete array[index]
, use array.splice
. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice for more info.
delete array[index]
array.splice
The next suggestion is to clarify whether you actually need to modify the array, or just get a new array without some of the original array's data. If you do not need to modify the original, it is far better to just use a function like reduce, or use a for loop to selectively copy items into the new array.
Using only ES6, you can use 2 reduce
s. First is to group the arrays. the second is to get the number of top per group.
reduce
let arr = [{"person":"Fred","scoreTotal":29},{"person":"Alice","scoreTotal":34},{"person":"Alice","scoreTotal":22},{"person":"Mary","scoreTotal":14},{"person":"Bob","scoreTotal":33},{"person":"Bob","scoreTotal":13},{"person":"Bob","scoreTotal":22},{"person":"Joe","scoreTotal":28}];
let getTop = (a, t) => {
return Object.values(a.reduce((c, v) => {
c[v.person] = c[v.person] || ;
c[v.person].push(v);
return c;
}, {})).reduce((c, v) => {
v.sort((a, b) => b.scoreTotal - a.scoreTotal);
c = c.concat(v.slice(0, t));
return c;
}, );
}
let result1 = getTop(arr, 1);
let result2 = getTop(arr, 2);
console.log(result1);
console.log(result2);
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.