过滤数组中重复值组的JavaScript函数失效问题排查
问题:重复的(x,y)组未被正确拦截
需要实现的功能:检查即将推入数组的由x、y组成的连续值组是否已按顺序存在于数组中,避免重复推入。但运行代码后发现部分重复的(x,y)组仍被推入,部分能被正确拦截。
用户编写的JavaScript代码:
let items = []; let x = 0; let y = 0; let xc = [0, 10, 15, 20]; let yc = [0, 10, 15, 20]; function fillArray() { for (let i = 0; i < 10; i++) { x = xc[Math.floor(Math.random() * xc.length)]; y = yc[Math.floor(Math.random() * yc.length)]; while (checkIfGroupExists(items, [x, y])) { console.log(`sequence ${x},${y} already exists.`); x = xc[Math.floor(Math.random() * xc.length)]; y = yc[Math.floor(Math.random() * yc.length)]; } items.push(x, y); } } function checkIfGroupExists(arr, sequence) { if (arr.length === 0) { return false; } const first = sequence[0]; let index = arr.indexOf(first, 0); while (index > -1) { if (sequence.every((v, i) => arr[index + i] === v)) { return true; } index = arr.indexOf(first, index); if (index == -1) { return false; } index++; } return false; } console.log(items);
核心问题分析
跨组匹配错误
你的items数组是按x,y成对扁平化存储的,每两个元素才是一个合法的(x,y)组,但原checkIfGroupExists函数会检查所有出现x的位置,包括奇数索引(也就是某个组的y值位置)。比如items是[20,15,10,20]时,检查[15,10]会错误匹配索引1和2的元素,但这根本不是一个合法的(x,y)组,只是前组的y和后组的x拼接的结果。索引遍历逻辑漏洞
原函数中查找下一个x的索引时,index = arr.indexOf(first, index)会重复检查当前位置,后续的index++又会导致跳过部分有效索引,容易出现漏查或误判的情况。
修复方案
修改checkIfGroupExists函数,只在偶数索引位置(合法的(x,y)组起始位置)进行匹配,逻辑更直接且准确:
let items = []; let x = 0; let y = 0; let xc = [0, 10, 15, 20]; let yc = [0, 10, 15, 20]; function fillArray() { for (let i = 0; i < 10; i++) { x = xc[Math.floor(Math.random() * xc.length)]; y = yc[Math.floor(Math.random() * yc.length)]; while (checkIfGroupExists(items, [x, y])) { console.log(`sequence ${x},${y} already exists.`); x = xc[Math.floor(Math.random() * xc.length)]; y = yc[Math.floor(Math.random() * yc.length)]; } items.push(x, y); } } function checkIfGroupExists(arr, sequence) { if (arr.length === 0) { return false; } // 只遍历偶数索引,每两个元素为一组检查 for (let i = 0; i < arr.length; i += 2) { if (arr[i] === sequence[0] && arr[i+1] === sequence[1]) { return true; } } return false; } fillArray(); console.log(items);
内容的提问来源于stack exchange,提问作者leo
相关产品推荐
相关产品推荐

