JavaScript for循环推入重复值问题排查求助
问题分析与解决
先给你拍板:这绝对不是Brave DevTools的bug,完全是代码逻辑没贴合你的需求导致的。
问题出在哪?
你写的代码逻辑是:把每个字符串切成前后两半,然后遍历前半段的每一个字符——只要后半段有这个字符,就往结果数组里塞。这就会导致一个问题:如果前半段里有重复的共同字符,它会被反复塞进数组。
拿你给的测试代码举例:
let totalData = ['testingt','stringhere','doesntmatttr']; let arr = []; for (let item of totalData) { if (item) { let comp1 = item.slice(0,item.length/2) let comp2 = item.slice(item.length/2) for (let char of comp1) if (comp2.includes(char)) { arr.push(char) } } } console.log(totalData.length, arr.length) // 输出3和5
第一个字符串testingt的前半段是test,里面有两个t,后半段ingt里也有t,所以这两个t都会被塞进数组;第二个字符串stringhere的前半段strin里只有一个r匹配后半段,塞一次;第三个字符串的前半段里有两个符合条件的字符,塞两次——加起来就是2+1+2=5,和你看到的结果完全对应。
你之前加的item != totalData[i-1]判断完全没用,因为你的问题根本不是重复处理了同一个数组元素,而是单个元素内部重复塞了字符。
怎么改?
你的需求是每个字符串取前后半段的共同字符,最终得到['t','r','t'],也就是每个字符串贡献一个结果。这里给两种方案:
方案1:找到第一个匹配的字符就停
如果只需要每个字符串的第一个共同字符,遍历前半段时找到匹配的就立刻停止:
let totalData = ['testingt','stringhere','doesntmatttr']; let arr = []; for (let item of totalData) { if (!item) continue; // 用Math.floor处理奇数长度的字符串,避免slice参数隐式转整数 let halfLen = Math.floor(item.length / 2); let comp1 = item.slice(0, halfLen); let comp2 = item.slice(halfLen); for (let char of comp1) { if (comp2.includes(char)) { arr.push(char); break; // 找到第一个就停,避免重复塞 } } } console.log(arr); // 输出 ['t','r','t'],完全符合预期
方案2:获取每个字符串的所有唯一共同字符
如果你需要每个字符串的所有去重后的共同字符(比如某个字符串前后半段有多个不同的共同字符),可以用Set去重:
let totalData = ['testingt','stringhere','doesntmatttr']; let arr = []; for (let item of totalData) { if (!item) continue; let halfLen = Math.floor(item.length / 2); let comp1 = item.slice(0, halfLen); let comp2 = item.slice(halfLen); // 先给前半段去重,再筛选出后半段也有的字符 let uniqueCommon = [...new Set(comp1)].filter(char => comp2.includes(char)); arr.push(...uniqueCommon); // 想每个字符串只塞一个的话,就用arr.push(uniqueCommon[0]) } console.log(arr); // 输出 ['t','r','t']
内容的提问来源于stack exchange,提问作者Raphael Morgan
相关产品推荐
相关产品推荐

