You need to enable JavaScript to run this app. 如何仅用一次循环为数组添加唯一id 无需两次循环实现
优惠活动
大模型
产品
解决方案
定价
更多

如何仅用一次循环为数组添加唯一id 无需两次循环实现

单次遍历实现嵌套数组扁平化+全局唯一自增ID的方案

核心思路:在遍历逻辑外维护全局自增计数器,或者利用结果数组的长度做天然计数,即可在一次遍历内完成嵌套元素收集+ID赋值,完全规避分组下标重复的问题。

固定两层嵌套结构(大部分GraphQL返回的常见场景)

如果你的返回结构固定是外层数组的每个元素下挂载items子数组,直接用嵌套forEach配合外部计数器即可,总遍历次数等于所有item的总数量,无额外开销:

// 示例原始数据,可根据你的实际返回结构调整字段名
const rawData = [
  { category: '1', items: [{ title: 'item1' }, { title: 'item2' }] },
  { category: '2', items: [{ title: 'item3' }, { title: 'item4' }, { title: 'item5' }] }
]

const res = []
let autoId = 0

rawData.forEach(group => {
  group.items.forEach(item => {
    res.push({
      ...item,
      id: autoId++
    })
  })
})

任意深度嵌套结构

如果存在不确定层级的嵌套items,可以用递归配合计数器实现,同样是单次遍历:

const res = []
let autoId = 0

function flatten (data) {
  data.forEach(node => {
    // 匹配带items的节点,可根据你的实际结构调整判断条件
    if (Array.isArray(node.items)) {
      node.items.forEach(item => {
        res.push({ ...item, id: autoId++ })
        // 递归处理子元素的嵌套items
        flatten([item])
      })
    }
  })
}

flatten(rawData)

纯函数式实现(无外部变量)

如果不想引入外部计数器,可以用reduce结合结果数组的天然长度做自增ID,逻辑更简洁:

const res = rawData.reduce((acc, group) => {
  return acc.concat(
    group.items.map(item => ({
      ...item,
      id: acc.length // 已存入的元素长度正好是下一个ID的取值
    }))
  )
}, [])

以上所有方案的时间复杂度均为O(n),n为所有待提取item的总数量,全程只有一次遍历逻辑,没有额外的二次遍历开销。

内容的提问来源于stack exchange,提问作者GʀᴜᴍᴘʏCᴀᴛ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 05:54:01