如何在JavaScript中获取数组内深层嵌套对象的首个唯一项
问题描述
现有如下结构的对象数组:
const arr = [ {id: 123, message: { user_id: 4, text: 'fish'}}, {id: 456, message: { user_id: 4, text: 'cow'}}, {id: 789, message: { user_id: 5, text: 'chicken'}}, {id: 10, message: { user_id: 5, text: 'turkey'}} ];
需要返回数组中每个message.user_id对应的首个唯一项,预期结果如下:
const newArr = [ {id: 123, message: { user_id: 4, text: 'fish'}}, {id: 789, message: { user_id: 5, text: 'chicken'}} ];
由于处理的是动态数据,无法硬编码user_id,且数组元素较多,希望尽可能避免循环,求最优实现方法。
解决方案
首先明确:JavaScript中处理这类需求无法完全避免遍历(否则无法逐个检查元素的user_id),但可以通过一次遍历完成,这是性能最优的方式。推荐两种高效实现方案:
方案一:使用reduce + Set(性能最优)
利用Set的O(1)查询特性,配合reduce单次遍历完成去重,同时保留每个user_id对应的首个元素:
const arr = [ {id: 123, message: { user_id: 4, text: 'fish'}}, {id: 456, message: { user_id: 4, text: 'cow'}}, {id: 789, message: { user_id: 5, text: 'chicken'}}, {id: 10, message: { user_id: 5, text: 'turkey'}} ]; const { result } = arr.reduce((acc, currentItem) => { const userId = currentItem.message.user_id; if (!acc.seenIds.has(userId)) { acc.seenIds.add(userId); acc.result.push(currentItem); } return acc; }, { seenIds: new Set(), result: [] }); console.log(result); // 输出符合预期的结果数组
优势
- 时间复杂度为O(n),仅需一次遍历
Set的成员查询效率高于普通对象,处理大规模数组时性能更优- 完全适配动态
user_id,无需硬编码
方案二:使用reduce + 普通对象(代码更简洁)
如果追求代码简洁,也可以用普通对象存储已出现的user_id,最后通过Object.values()提取结果:
const arr = [ {id: 123, message: { user_id: 4, text: 'fish'}}, {id: 456, message: { user_id: 4, text: 'cow'}}, {id: 789, message: { user_id: 5, text: 'chicken'}}, {id: 10, message: { user_id: 5, text: 'turkey'}} ]; const newArr = Object.values(arr.reduce((acc, item) => { const userId = item.message.user_id; // 仅当该user_id未被记录时保存当前元素 if (!acc[userId]) { acc[userId] = item; } return acc; }, {})); console.log(newArr); // 输出符合预期的结果数组
优势
- 代码更紧凑,实现成本低
- 同样是单次遍历,时间复杂度O(n),性能与方案一接近
内容的提问来源于stack exchange,提问作者Awesome Bassey
相关产品推荐
相关产品推荐

