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 reduces. 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.

Popular posts from this blog

api-platform.com Unable to generate an IRI for the item of type

How to set up datasource with Spring for HikariCP?

Display dokan vendor name on Woocommerce single product pages