
本文介绍使用 JavaScript 的 filter 与 findIndex 组合,基于字符串中特定位置的 ID 字段(如 code1-code2-id- 中的 id)去重数组,确保每个 ID 仅保留首次出现的元素,代码简洁、可读性强且无需额外存储结构。
本文介绍使用 javascript 的 filter 与 findindex 组合,基于字符串中特定位置的 id 字段(如 `code1-code2-id-` 中的 `id`)去重数组,确保每个 id 仅保留首次出现的元素,代码简洁、可读性强且无需额外存储结构。
在处理结构化字符串数组(如 "code1-code2-id-" 格式)时,常需按某一段子串(例如 id)去重,而非整个字符串。此时,简单使用 Set 或 filter + includes 无法直接满足需求,关键在于精准提取并比对语义 ID。
核心思路是:对每个元素,提取其 id 值,并检查该 id 在原数组中首次出现的索引是否等于当前元素索引。若相等,说明这是该 id 的首次出现,应保留;否则跳过。这一逻辑天然保证了“保留第一个”的确定性行为,且时间复杂度为 O(n²),在中等规模数据下性能完全可接受。
以下为推荐实现:
const links = [
"13989664-34-1-",
"3588867-34-1-",
"4757546-34-2-",
"72469424-34-2-"
];
// 安全提取 id:按 '-' 分割后取第 3 段(索引 2),并移除末尾 '-'(如有)
const getId = (str) => {
const parts = str.split('-');
return parts.length >= 3 ? parts[2].replace(/-$/, '') : '';
};
const uniqueLinks = links.filter((item, index) =>
links.findIndex(other => getId(other) === getId(item)) === index
);
console.log(uniqueLinks);
// 输出: ["13989664-34-1-", "4757546-34-2-"]✅ 优势说明:
- 语义清晰:getId() 封装解析逻辑,便于复用与维护;
- 健壮性强:replace(/-$/, '') 处理末尾可能存在的冗余 -,避免 id 提取错误;
- 无副作用:不修改原数组,符合函数式编程原则;
- 零依赖:纯原生 JS,兼容所有现代环境。
⚠️ 注意事项:
- 若 id 可能为空或格式异常(如少于 3 个 -),getId() 已做防御性处理,返回空字符串,此时所有空 id 将被归为同一组——仅保留第一个。如需更严格校验,可补充正则匹配(如 /-(\d+)-$/);
- 对超大规模数组(>10⁴ 元素),O(n²) 性能可能成为瓶颈,此时建议改用 Map 一次遍历优化(见进阶方案):
// 进阶:O(n) 时间复杂度方案(适用于大数据量)
const uniqueLinksOptimized = Array.from(
links.reduce((map, item) => {
const id = getId(item);
if (!map.has(id)) map.set(id, item);
return map;
}, new Map()).values()
);综上,filter + findIndex 方案在简洁性、可读性与实用性上达到优秀平衡,是此类字符串 ID 去重任务的首选实践。










