
本文介绍一种使用 set 去重结合函数式方法高效提取两字符串(或字符串数组与目标字符串)间公共字母的方案,彻底解决传统嵌套 for 循环因重复字符导致结果冗余的问题。
本文介绍一种使用 set 去重结合函数式方法高效提取两字符串(或字符串数组与目标字符串)间公共字母的方案,彻底解决传统嵌套 for 循环因重复字符导致结果冗余的问题。
在字符串比对场景中,若直接使用双重 for 循环逐字符比较(尤其当某字符串含重复字母时),极易产生重复匹配——例如 "Apple" 与 "apple" 比较时,字母 'p' 和 'e' 各出现两次,若未去重,就会被多次计入结果,造成 'aaaaaa' 这类非预期输出。
根本原因在于:原始代码中 fruit[i] 遍历的是原始字符串的每个位置(含重复字符),而 myString[j].indexOf(fruit[i]) 的写法本身也有逻辑错误(myString[j] 是单个字符,indexOf 不适用;且 return myString(j) 语法非法)。更关键的是,它缺乏对“字母是否已匹配过”的状态管理。
✅ 正确解法是语义化处理:我们真正关心的不是“每个位置是否相等”,而是“哪些字母同时存在于两个字符串中”。因此应先将字符串转为小写,再用 Set 提取唯一字符,实现天然去重:
const fruits = ["Banana", "Orange", "Apple", "Mango", "Apple"];
let myString = "apple";
const findCommonLetters = (array, string) => {
const uniqueStringLetters = new Set(string.toLowerCase()); // → Set {'a','p','l','e'}
return array.map(fruit =>
[...new Set(fruit.toLowerCase())] // 每个水果去重后转数组,如 "apple" → ['a','p','l','e']
.filter(letter => uniqueStringLetters.has(letter)) // 仅保留在 myString 中也存在的字母
.join('') // 合并为字符串,如 "apple" → "aple"
);
};
console.log(findCommonLetters(fruits, myString));
// 输出: ["aple", "", "aple", "", "aple"]
? 注意事项:
-
Set构造确保每个字母仅被检查一次,从根本上杜绝重复; -
map+filter替代嵌套循环,代码更清晰、可维护性更高; - 若只需全局共有的字母(而非每个水果单独计算),可进一步用
flat()+new Set()聚合去重; - 大小写敏感性通过统一
toLowerCase()控制,如需区分大小写,请按需调整。
该方法兼顾性能与可读性,是处理字符级交集问题的推荐实践。










