Javascript 如何根据属性值比较和筛选数组的对象?

Javascript 如何根据属性值比较和筛选数组的对象?,javascript,Javascript,我有以下数据结构: persons: [ { name: 'Joe', age: 20 }, { name: 'Alex', age: 24 }, { name: 'Joe', age: 34 }, { name: 'Bob', age: 19 }, { name: 'Alex', age: 56 }, ] 我希望为每个现有名称获取最老的person对象。所以这个例子的结果是: filteredPersons: [ { name: 'Joe', ag

我有以下数据结构:

persons: [
  { name: 'Joe',  age: 20 },
  { name: 'Alex', age: 24 },  
  { name: 'Joe',  age: 34 },  
  { name: 'Bob',  age: 19 },  
  { name: 'Alex', age: 56 },
]
我希望为每个现有名称获取最老的person对象。所以这个例子的结果是:

filteredPersons: [
  { name: 'Joe',  age: 34 },  
  { name: 'Bob',  age: 19 },  
  { name: 'Alex', age: 56 },
]

我怎样才能做到这一点?请注意,不同名称的数量不是固定的。

要在一次传递中实现这一点,您可以使用将
名称
作为键的构建,并将最大
年龄
名称
一起存储为值对象

Map
准备就绪后,您可以使用以下方法提取其值:

const src=[{name:'Joe',age:20},{name:'Alex',age:24},{name:'Joe',age:34},{name:'Bob',age:19},{name:'Alex',age:56},],
结果=[…src
.reduce((acc,{name,age})=>{
const match=acc.get(名称)
比赛?
match.age=Math.max(age,match.age):
acc.set(name,{name,age})
返回acc
},新地图)
.values()
]
console.log(结果)
。作为控制台包装器{min height:100%;}
您可以选择一个名称,并收集相同名称的较旧版本

此解算器具有一个比较两个对象(或一个对象和一个可能的
未定义的
)的功能,如果truthy和
b.age
大于
a.age
,则返回
b
,否则返回
a

最后,仅将贴图的值作为结果集

const
老年人=(a,b)=>b?.age>a.age?b:a,
persons=[{name:'Joe',年龄:20},{name:'Alex',年龄:24},{name:'Joe',年龄:34},{name:'Bob',年龄:19},{name:'Alex',年龄:56}],
结果=数组.from(persons.reduce)((m,o)=>m.set(
o、 名字,
年长者(o,m.get(o.name))
),新映射)。值());
控制台日志(结果)

.as console wrapper{max height:100%!important;top:0;}
简单地减少数组,对于数组中的每个人,检查是否以前遇到过该项,如果是,保留最旧的项,否则只保留当前对象:

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
演示:

let persons=[{name:'Joe',age:20},{name:'Alex',age:24},{name:'Joe',age:34},{name:'Bob',age:19},{name:'Alex',age:56}];
让结果=人。减少((acc,人)=>{
如果(!acc[person.name]| acc[person.name].agelog(“arrayResults:”,arrayResults)希望这对您来说更容易理解

const persons=[
{姓名:'Joe',年龄:20},
{姓名:'Alex',年龄:24},
{姓名:'Joe',年龄:34},
{姓名:'Bob',年龄:19},
{姓名:'Alex',年龄:56},
]
让personsObj={},mxPersons=[]
persons.forEach(person=>{
if(personsObj[person.name]==未定义){
personsObj[person.name]=person.age
}否则{
personsObj[person.name]=Math.max(person.age,personsObj[person.name])
}
})
for(Object.entries(personsObj))的常量[key,value]{
推({
姓名:key,,
年龄:价值
})
}

console.log(mxPersons)
首先根据姓名对所有人进行分组,然后取每组中最年长的人,即可获得每个姓名中最年长的人

这个答案确实引入了两个助手函数
groupBy
maxBy
,它们增加了一些开销,但在一般情况下确实很有用

const people=[
{姓名:'Joe',年龄:20},
{姓名:'Alex',年龄:24},
{姓名:'Joe',年龄:34},
{姓名:'Bob',年龄:19},
{姓名:'Alex',年龄:56},
];
const oldestPeople=数组
.from(groupBy(people,person=>person.name).values())
.map(people=>maxBy(people,person=>person.age));
console.log(最老的人);
函数groupBy(iterable,fn){
常量组=新映射();
用于(iterable的常数项){
常数键=fn(项目);
如果(!groups.has(key))groups.set(key,[]);
组。获取(键)。推送(项);
}
返回组;
}
函数maxBy(iterable,fn){
设max,maxValue;
用于(iterable的常数项){
const itemValue=fn(项目);

if(itemValue)您是否只想要其中3项是对象上最古老的内容?@VinceSanchezTañan我想要的内容与名称的数量一样多我有使用数组的解决方案(可以读取)但它是从最高点排序的。你同意吗?我最后使用了你和尼娜的答案,但不幸的是,我不得不决定接受哪一个。非常感谢anyway@leonheess:事实上,它们几乎完全相同,因此没有什么可组合的(除了我的,这是由于一些技巧)然而,如果你发现另一个答案更全面,你完全可以自由选择。
let arrayResults = Object.values(results);