JS中对标签名数组不区分大小写去重需统一转小写比较但保留原始值,推荐用Map保序去重,filter+findIndex适合小数组,直接Set会丢失原始大小写格式。

JS 中对标签名数组进行不区分大小写去重,核心在于:**统一转为小写(或大写)做比较,但保留原始值**。不能直接用 Set 或 indexOf 原始数组,因为 "DIV" 和 "div" 在 JS 中是两个不同字符串,会被视为不重复。
用 Map 记录小写形式,保序去重(推荐)
这是最清晰、高效且兼容性好的方式,能准确识别大小写变体,同时保持首次出现的原始格式。
- 遍历原数组,把每个标签名转成小写作为 key 存入 Map
- 只有该小写形式未出现过时,才把原始标签名推入结果数组
- 天然保持原顺序,不修改原数组,支持任意字符串(包括空格、特殊字符)
示例代码:
function uniqueTagNames(arr) {
const seen = new Map();
const result = [];
for (const tag of arr) {
const lower = tag.toLowerCase();
if (!seen.has(lower)) {
seen.set(lower, true);
result.push(tag);
}
}
return result;
}
const tags = ["DIV", "span", "IMG", "div", "Span", "a"];
console.log(uniqueTagNames(tags)); // ["DIV", "span", "IMG", "a"]
用 filter + findIndex(简洁写法)
适合喜欢函数式风格、数组较小时使用。逻辑明确:只保留「当前项的小写形式在数组中第一次出现的位置等于当前索引」的元素。
- 每次调用
findIndex都会从头找,性能略低于 Map 方案(O(n²)) - 代码短,可读性强,ES6+ 环境下直接可用
示例代码:
const uniqueTagNames = (arr) =>
arr.filter((tag, i) =>
arr.findIndex(t => t.toLowerCase() === tag.toLowerCase()) === i
);
注意对象/复杂结构不适用这些方法
以上方案仅适用于字符串型标签名(如 "div", "SECTION")。如果数组里混有 DOM 元素、对象或 null/undefined,需先过滤或额外判断:
- 加类型检查:
typeof tag === 'string' && tag.trim() - 忽略空值:
if (!tag || typeof tag !== 'string') continue; - DOM 元素要取
el.tagName后再处理
为什么不直接用 Set + toLowerCase?
像 [...new Set(arr.map(t => t.toLowerCase()))] 这样会返回小写字符串数组(如 ["div", "span"]),丢失原始大小写格式。而实际开发中,标签名通常需要保留原始书写习惯(比如 Vue 组件名、HTML 模板规范),所以必须分离「判重依据」和「输出值」。


















