如何从多个对象集合中提取唯一值存入数组?求多实现方案
多个对象值存入数组并保证唯一性的最优实现方案
嘿,很高兴帮你搞定这个邮箱去重的问题!你当前的代码能把owners和members里的邮箱都收集到数组里,但确实会出现重复项。下面我给你几种不同的实现思路,从简洁高效到兼容旧环境的都有,你可以根据自己的场景选:
方案1:ES6 Set 简洁去重(推荐)
这是目前最简洁的实现方式,利用Set自动去重的特性,一行代码就能搞定:
const emails = [...new Set([...owners.map(o => o.mail), ...members.map(m => m.mail)])];
解释:
- 先通过
map分别提取owners和members里的邮箱,得到两个邮箱数组 - 用扩展运算符
...把两个数组合并成一个 - 把合并后的数组传入
Set构造函数,自动过滤重复项 - 再用
...把Set转回数组,得到唯一的邮箱列表
这种写法可读性强,代码简洁,适合大多数现代环境,数据量不大时性能完全够用。
方案2:收集后用filter过滤去重(兼容旧环境)
如果需要兼容不支持ES6的旧环境,可以先收集所有邮箱,再用filter结合indexOf去重:
let emails = []; // 先收集所有邮箱 owners.forEach(data => emails.push(data.mail)); members.forEach(data => emails.push(data.mail)); // 过滤出仅第一次出现的邮箱 const uniqueEmails = emails.filter((mail, index, self) => self.indexOf(mail) === index);
解释:
filter会遍历数组,只保留indexOf(mail)等于当前索引的元素——也就是这个邮箱在数组里第一次出现的位置,后续重复的都会被过滤掉。不过这种方式的时间复杂度是O(n²),数据量很大时性能不如Set方案。
方案3:边收集边去重(内存高效)
如果你的owners和members数组很大,不想先存一堆重复值再过滤,可以在收集的时候就用Set去重,节省内存:
const emailSet = new Set(); // 遍历的时候直接加入Set,自动忽略重复项 owners.forEach(data => emailSet.add(data.mail)); members.forEach(data => emailSet.add(data.mail)); // 转成最终数组 const emails = Array.from(emailSet);
解释:
Set的add方法会自动判断元素是否已存在,不存在才会添加。这种方式不需要先存储所有重复的邮箱,内存占用更低,大数据量场景下更高效。
方案4:函数式风格的reduce去重
如果你喜欢函数式编程的写法,可以用reduce来合并和去重:
const uniqueEmails = Array.from( [...owners, ...members].reduce((acc, curr) => { acc.add(curr.mail); return acc; }, new Set()) );
解释:
- 先合并
owners和members数组 - 用
reduce遍历每个对象,把邮箱添加到Set里(自动去重) - 最后把Set转成数组,得到唯一邮箱列表
这种写法比较紧凑,适合习惯函数式风格的开发者。
总结
- 现代环境优先选方案1或方案3:方案1最简洁,方案3在大数据量下更高效
- 旧环境兼容选方案2
- 函数式偏好选方案4
内容的提问来源于stack exchange,提问作者Ciprian
相关产品推荐
相关产品推荐

