如何优雅移除数组中含相同id的重复字符串元素?
问题
我有一个包含多个字符串元素的数组,所有元素的格式均为:
code1-code2-id-
其中code1在每个字符串中各不相同,code2始终保持一致。我需要移除数组中具有相同id的元素。
示例:
输入:
const links = ["13989664-34-1-","3588867-34-1-","4757546-34-2-" ,"72469424-34-2-"]
期望输出:
["13989664-34-1-","4757546-34-2-"]
注:无需指定保留第一个或第二个重复项,任意保留其一即可。
我已经尝试了以下解决方案,想了解是否有更优雅的实现方式:
const links = [ "13989664-34-1-", "3588867-34-1-", "4757546-34-2-", "72469424-34-2-", ]; const uniqueLinks = []; links.forEach((link, index) => { console.log(index); const linkId = link.substring(link.length - 2, link.length - 1); if (index == 0) uniqueLinks.push(link); else if ( !uniqueLinks.find((l) => l.substring(l.length - 2, l.length - 1) == linkId) ) { uniqueLinks.push(link); } });
更优雅的实现方式
方法一:用Map快速去重(高效直观)
Map的存在性判断是O(1)操作,遍历一次数组就能完成去重,时间复杂度比原方案的O(n²)更优:
const links = ["13989664-34-1-","3588867-34-1-","4757546-34-2-" ,"72469424-34-2-"]; const idMap = new Map(); const uniqueLinks = links.reduce((acc, link) => { // 分割字符串提取ID,比依赖长度的substring更可靠(ID位数变化也兼容) const parts = link.split('-'); const id = parts[2]; if (!idMap.has(id)) { idMap.set(id, true); acc.push(link); } return acc; }, []); console.log(uniqueLinks); // ["13989664-34-1-","4757546-34-2-"]
方法二:用普通对象记录(兼容性更强)
如果不需要Map的特性,用普通对象也能实现同样效果,兼容更早的JS环境:
const links = ["13989664-34-1-","3588867-34-1-","4757546-34-2-" ,"72469424-34-2-"]; const idRecord = {}; const uniqueLinks = []; for (const link of links) { const id = link.split('-')[2]; if (!idRecord[id]) { idRecord[id] = true; uniqueLinks.push(link); } } console.log(uniqueLinks);
方法三:一行式简洁实现
追求代码精简的话,可以用reduce生成以ID为键的对象,再转成数组:
const links = ["13989664-34-1-","3588867-34-1-","4757546-34-2-" ,"72469424-34-2-"]; const uniqueLinks = Object.values(links.reduce((obj, link) => { const id = link.split('-')[2]; if (!obj[id]) obj[id] = link; return obj; }, {})); console.log(uniqueLinks);
这些方案的优势:
- 可靠性更高:用
split提取ID,避免了原方案中依赖字符串长度的潜在风险 - 效率更好:仅遍历一次数组,存在性判断为O(1),整体时间复杂度O(n)
- 逻辑更清晰:去掉了索引判断和嵌套的
find操作,代码可读性更强
内容的提问来源于stack exchange,提问作者Maryam Moshtoofar
相关产品推荐
相关产品推荐

