我正在学习JS。假设我有以下对象数组:
var family = [
{
name: "Mike",
age: 10
},
{
name: "Matt"
age: 13
},
{
name: "Nancy",
age: 15
},
{
name: "Adam",
age: 22
},
{
name: "Jenny",
age: 85
},
{
name: "Nancy",
age: 2
},
{
name: "Carl",
age: 40
}
];
注意,Nancy出现了两次(只改变了年龄)。假设我只想输出唯一的名称。如何输出上述对象数组,而不重复?ES6答案非常受欢迎。
相关(找不到在对象上使用的好方法):
编辑这是我尝试的。它适用于字符串,但我不知道如何使它适用于对象:
family.reduce((a, b) => {
if (a.indexOf(b) < 0 ) {
a.push(b);
}
return a;
},[]);
您可以将集与数组#映射和扩展运算符结合使用代码>在单行中。
Map返回一个包含所有名称的数组,这些名称将进入集合初始化程序,然后集合的所有值都在一个数组中返回。
var family = [{ name: "Mike", age: 10 }, { name: "Matt", age: 13 }, { name: "Nancy", age: 15 }, { name: "Adam", age: 22 }, { name: "Jenny", age: 85 }, { name: "Nancy", age: 2 }, { name: "Carl", age: 40 }],
unique = [...new Set(family.map(a => a.name))];
console.log(unique);
在对象中存储循环外部的name
的出现次数,并过滤是否存在先前的出现次数。
https://jsfiddle.net/nputptbb/2/
var occurrences = {}
var filteredFamily = family.filter(function(x) {
if (occurrences[x.name]) {
return false;
}
occurrences[x.name] = true;
return true;
})
您也可以将此解决方案推广到函数
function filterByProperty(array, propertyName) {
var occurrences = {}
return array.filter(function(x) {
var property = x[propertyName]
if (occurrences[property]) {
return false;
}
occurrences[property]] = true;
return true;
})
}
并像这样使用它
var filteredFamily = filterByProperty(family, 'name')
不要使用indexOf比较对象,indexOf只在对象之间使用操作符。您当前的答案不起作用的原因是,JS中没有深入比较对象,而是比较引用。我的意思是,您可以在以下代码中看到:
var a = { x: 1 }
var b = { x: 1 }
console.log(a === b) // false
console.log(a === a) // true
等式将告诉您是否找到了相同的精确对象,但不会告诉您是否找到了具有相同内容的对象。
在这种情况下,您可以在名称上比较对象,因为它应该是唯一的键。Soobj。名称===对象。名称,而不是obj===obj。此外,代码的另一个影响其运行时而非功能的问题是,在您的reduce中使用了索引of
O(1)查找的对象。indexOf是O(n)
,这使得算法的复杂性增加。因此,最好使用具有
这很好用。
const result = [1, 2, 2, 3, 3, 3, 3].reduce((x, y) => x.includes(y) ? x : [...x, y], []);
console.log(result);