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

JS对象数组按指定属性去重并合并另一属性值为数组的实现

解决方案

你当前的filter方案只能保留首次出现的条目,无法对后续重复条目的属性做合并,改用Map做临时存储即可实现需求:

适配当前场景的实现

function dedupeAndMergeUrl(keyFn, array) {
  const map = new Map()
  array.forEach(item => {
    const key = keyFn(item)
    if (!map.has(key)) {
      // 首次遇到对应key,拷贝对象并将url转为数组格式存储
      map.set(key, { ...item, url: [item.url] })
    } else {
      // 已存在同key条目,追加url到数组
      map.get(key).url.push(item.url)
      // 如果需要避免url重复可以替换成下面的写法
      // const existedItem = map.get(key)
      // if (!existedItem.url.includes(item.url)) existedItem.url.push(item.url)
    }
  })
  // 将Map的值转为数组返回
  return Array.from(map.values())
}

// 调用方式和你原有逻辑一致
const dedupedArray = dedupeAndMergeUrl((x) => x.name, originalArray)

通用版实现(支持自定义合并属性)

/**
 * 按指定属性去重数组,同时合并指定字段为数组
 * @param {Function} keyFn 生成去重key的方法
 * @param {Array} array 原数组
 * @param {String} mergeField 需要合并的属性名
 * @param {Boolean} uniqueMergeField 合并后的数组是否要去重,默认false
 */
function dedupeAndMerge(keyFn, array, mergeField, uniqueMergeField = false) {
  const map = new Map()
  array.forEach(item => {
    const key = keyFn(item)
    if (!map.has(key)) {
      map.set(key, { ...item, [mergeField]: [item[mergeField]] })
    } else {
      const target = map.get(key)
      const currentVal = item[mergeField]
      if (!uniqueMergeField || !target[mergeField].includes(currentVal)) {
        target[mergeField].push(currentVal)
      }
    }
  })
  return Array.from(map.values())
}

// 调用示例
const dedupedArray = dedupeAndMerge(x => x.name, originalArray, 'url', true)

注意事项

  • 上述代码用对象扩展运算符...做浅拷贝,如果你的对象包含深层嵌套属性,需要替换为深拷贝逻辑
  • 重复条目的非合并属性(示例中的id、description)默认取首次出现的条目值,如果需要取最后一次出现的值,可在追加合并属性的同时,覆盖对应非合并属性即可

内容的提问来源于stack exchange,提问作者mheavers

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 14:15:03