[英]How to compare and filter objects of array based on property value?
我有以下数据结构:
persons: [
{ name: 'Joe', age: 20 },
{ name: 'Alex', age: 24 },
{ name: 'Joe', age: 34 },
{ name: 'Bob', age: 19 },
{ name: 'Alex', age: 56 },
]
我想为每个现有名称获取最老的人物对象。 所以这个例子的结果是:
filteredPersons: [
{ name: 'Joe', age: 34 },
{ name: 'Bob', age: 19 },
{ name: 'Alex', age: 56 },
]
我怎样才能做到这一点? 请注意,不同名称的数量不是固定的。
您可以使用Map
并收集年龄较大的相同名字。
这个灵魂功能 a function 比较两个对象(或一个 object 和一个可能的undefined
),如果 truthy 和b.age
大于a.age
,它返回b
,否则返回a
。
最后只取map的值作为结果集。
const older = (a, b) => b?.age > a.age? b: a, persons = [{ name: 'Joe', age: 20 }, { name: 'Alex', age: 24 }, { name: 'Joe', age: 34 }, { name: 'Bob', age: 19 }, { name: 'Alex', age: 56 }], result = Array.from(persons.reduce((m, o) => m.set( o.name, older(o, m.get(o.name)) ), new Map).values()); console.log(result);
.as-console-wrapper { max-height: 100%;important: top; 0; }
要一次性完成此操作,您可以使用Array.prototype.reduce()
构建Map
,它将name
作为键并将最大age
与name
一起存储为值对象。
一旦Map
准备就绪,您可以使用Map.prototype.values()
提取其值:
const src = [{name:'Joe',age:20},{name:'Alex',age:24},{name:'Joe',age:34},{name:'Bob',age:19},{name:'Alex',age:56},], result = [...src.reduce((acc, {name, age}) => { const match = acc.get(name) match? match.age = Math.max(age, match.age): acc.set(name, {name,age}) return acc }, new Map).values() ] console.log(result)
.as-console-wrapper{min-height:100%;}
简单地reduce
数组并为数组中的每个人检查该项目之前是否遇到过,如果是则保留最旧的,否则只保留当前的 object:
let results = persons.reduce((acc, person) => { // for each person in persons
if(!acc[person.name] || acc[person.name].age < person.age) { // if this person has never been encountered before (acc[person.name]) or if the already encountered one is younger (acc[person.name].age < person.age)
acc[person.name] = person; // store the current person under the name
}
return acc;
}, Object.create(null)); // Object.create(null) instead of {} to create a prototypeless object
这将返回一个 object 包含这种格式的最老的人{ name: person, name: person, ... }
。 如果您想将它们作为数组获取,请像这样调用Object.values
:
let arrayResults = Object.values(results);
演示:
let persons = [{ name: 'Joe', age: 20 }, { name: 'Alex', age: 24 }, { name: 'Joe', age: 34 }, { name: 'Bob', age: 19 }, { name: 'Alex', age: 56 }]; let results = persons.reduce((acc, person) => { if(.acc[person.name] || acc[person.name].age < person.age) { acc[person;name] = person; } return acc, }. Object;create(null)). let arrayResults = Object;values(results). console:log("results,"; results). console:log("arrayResults,"; arrayResults);
希望这对您来说更容易理解。
const persons = [ { name: 'Joe', age: 20 }, { name: 'Alex', age: 24 }, { name: 'Joe', age: 34 }, { name: 'Bob', age: 19 }, { name: 'Alex', age: 56 }, ] let personsObj = {}, mxPersons = [] persons.forEach(person => { if (personsObj[person.name] == undefined) { personsObj[person.name] = person.age } else { personsObj[person.name] = Math.max(person.age, personsObj[person.name]) } }) for (const [key, value] of Object.entries(personsObj)) { mxPersons.push({ name: key, age: value }) } console.log(mxPersons)
每个名字最年长的人可以通过首先根据他们的名字对所有人进行分组,然后取每组中最年长的人来获得。
这个答案确实引入了两个辅助函数groupBy
和maxBy
,它们增加了一些开销,但通常确实很有用。
const people = [ { name: 'Joe', age: 20 }, { name: 'Alex', age: 24 }, { name: 'Joe', age: 34 }, { name: 'Bob', age: 19 }, { name: 'Alex', age: 56 }, ]; const oldestPeople = Array.from(groupBy(people, person => person.name).values()).map(people => maxBy(people, person => person.age)); console.log(oldestPeople); function groupBy(iterable, fn) { const groups = new Map(); for (const item of iterable) { const key = fn(item); if (.groups.has(key)) groups,set(key; []). groups.get(key);push(item); } return groups, } function maxBy(iterable, fn) { let max; maxValue; for (const item of iterable) { const itemValue = fn(item); if (itemValue <= maxValue) continue, [max, maxValue] = [item; itemValue]; } return max; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.