如何基于子字符串 ID 去除数组中的重复项

1次阅读

如何基于子字符串 ID 去除数组中的重复项

本文介绍一种简洁、函数式的方法,使用 filter() 与 findindex() 配合提取规则化字符串(如 “code1-code2-id-“)中的 id 段,实现按 id 去重,保留每个 id 的首次出现项。

本文介绍一种简洁、函数式的方法,使用 filter() 与 findindex() 配合提取规则化字符串(如 “code1-code2-id-“)中的 id 段,实现按 id 去重,保留每个 id 的首次出现项。

在处理结构化字符串数组时,常需依据某一段子字符串(如 ID)进行逻辑去重,而非整个字符串的完全匹配。例如,给定数组:

const links = ["13989664-34-1-",   "3588867-34-1-",   "4757546-34-2-",   "72469424-34-2-"];

所有字符串均符合 code1-code2-id- 格式,其中 code2 固定(如 “34”),而 id(即第三个 – 分隔段)是去重的关键依据。目标是 对每个唯一 id,仅保留其首次出现的完整字符串,最终得到 [“13989664-34-1-“, “4757546-34-2-“]。

✅ 推荐解法:filter + findIndex(语义清晰、一行核心逻辑)

function getId(str) {return str.split("-")[2]; // 提取第三段(索引为 2),即 id 部分 }  const uniqueLinks = links.filter((item, index) =>    links.findIndex(x => getId(x) === getId(item)) === index );  console.log(uniqueLinks); // → ["13989664-34-1-", "4757546-34-2-"]

原理说明
对每个元素 item,我们查找整个数组中 第一个与其 id 相同的元素的索引;若该索引恰好等于 item 当前位置 index,说明它是该 id 的首次出现,应保留;否则跳过。此方法天然保证稳定性(始终保留首个),且无需额外状态变量或循环嵌套。

⚠️ 注意事项与优化建议

  • ID 提取要健壮:若字符串格式可能存在异常(如缺失 – 或长度不足),建议增强 getId:
    function getId(str) {const parts = str.split("-");   return parts.length >= 3 ? parts[2] : ""; }
  • 性能考量:该方案时间复杂度为 O(n²),适用于中小规模数组(< 10k 项)。若数据量极大,可改用 Set + 单次遍历的 O(n) 方案:
    const seenIds = new Set(); const uniqueLinks = links.filter(item => {   const id = getId(item);   if (seenIds.has(id)) return false;   seenIds.add(id);   return true; });
  • 灵活性扩展 :若需保留 最后一个 而非第一个匹配项,可将 findIndex 替换为 lastIndexOf(需先映射出 ID 数组)或改用 reduceRight。

✅ 总结

基于子字符串去重的核心在于 抽象出可比键(key),再结合数组高阶方法实现声明式逻辑。filter + findIndex 组合兼具可读性、简洁性与正确性,是处理此类结构化字符串去重的推荐范式。实际开发中,建议将 getId 封装为纯函数,并根据数据质量决定是否添加边界校验。

text=ZqhQzanResources