You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:45:49