[
{"score": 99, "group":"1"},
{"score": 90, "group":"2"},
{"score":"10", "group":"1"},
{"score":"10", "group":"2"},
]
I work with TypeOrm now and want to filter data.
Expected array:
[
{"score": 99, "group":"1"},
{"score": 90, "group":"2"},
]
CodePudding user response:
const data = [
{"score": 99, "group":"1"},
{"score": 90, "group":"2"},
{"score": 10, "group":"1"},
{"score": 10, "group":"2"}]
const result = [...new Set(data.map(i=>i.group))] // get unique group ids
.map(g=>data.filter(({group})=>g===group) // find members of each group
.sort(({score:a},{score:b})=>a-b).pop()) // find the one with highest score
console.log(result)
If your data includes scores that are strings instead of numbers, change a-b
to ( a)-( b)
to coerce the strings to numbers.
CodePudding user response:
I would use Lodash in this case
function maxGroups() {
let arr = [
{"score": 99, "group":"1"},
{"score": 90, "group":"2"},
{"score": 10, "group":"1"},
{"score": 10, "group":"2"},
]
let newArr = _.groupBy(arr, "group")
let result = _.map(newArr, i => (_.maxBy(i, 'score')));
console.dir(result)
}
CodePudding user response:
You could take a single loop approach with an object for keeping the groups.
const
data = [{ score: 99, group: "1" }, { score: 90, group: "2" }, { score: 10, group: "1" }, { score: 10, group: "2" }],
maxScore = Object.values(data.reduce((r, o) => {
if (!r[o.group] || r[o.group].score < o.score) r[o.group] = o;
return r;
}, {}));
console.log(maxScore);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
You can simply group by group
keeping only the objects with the highest score
. Here accumulating into a Map
and then spreading the iterator returned by Map.values()
as the result.
const input = [{ score: 99, group: '1' }, { score: 90, group: '2' }, { score: '10', group: '1' }, { score: '10', group: '2' },];
const reduced = input.reduce(
(a, o) =>
!a.has(o.group) || o.score > a.get(o.group)?.score
? a.set(o.group, { ...o })
: a,
new Map()
);
const result = [...reduced.values()];
console.log(result);
CodePudding user response:
For fun, here is another version:
const data = [
{"score": 99, "group":"1"},
{"score": 90, "group":"2"},
{"score": 10, "group":"1"},
{"score": 10, "group":"2"},
]
const maxByGroup = {}
for(const entry of data){
const max = maxByGroup[entry.group]
maxByGroup[entry.group] = max && max.score >= entry.score ? max : entry
}
const result = Object.values(maxByGroup)
console.log(result)
Probably the simplest way to do it, arguably the easiest to read, happens to be the fastest, too