You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

对象键值自增失效导致手机号重复数字校验函数输出异常的问题排查

对象键值自增失效导致手机号重复数字校验函数输出异常的问题排查

我帮你梳理下代码里的几个关键问题,这就是为什么你的输出和预期不符的原因:


问题1:计数逻辑的判断条件错误,导致数字重复次数统计异常

你现在的计数逻辑是:

if (!tempObj[el[j]]) {
  tempObj[el[j]] = 0;
} else if (tempObj) {
  tempObj[el[j]] = tempObj[el[j]] + 1;
}

这里的!tempObj[el[j]]会把值为0的情况也当成“键不存在”,因为0在JS里是假值。比如第一次统计数字8时,tempObj['8']undefined,进入第一个分支设为0;第二次遇到8时,!0true,又会进入第一个分支把值重置为0,永远无法完成自增。

另外你写的else if (tempObj)完全没必要,tempObj是你刚声明的对象,肯定存在,直接用else就行。

正确的计数写法可以简化成:

const em = el[j];
// 如果键不存在,默认给0,然后加1;存在的话直接加1
tempObj[em] = (tempObj[em] || 0) + 1;

或者更严谨的判断键是否存在:

const em = el[j];
if (!(em in tempObj)) {
  tempObj[em] = 1; // 第一次出现直接设为1
} else {
  tempObj[em] += 1;
}

问题2:结果判断的逻辑完全颠倒,导致符合条件的手机号被误判

你的需求是只要手机号里有任意一个数字重复3-4次,就返回"Yes",否则返回"No",但你现在的for-in循环逻辑是:

for (const num in tempObj) {
  if (tempObj[num] < 3 || tempObj[num] > 4) {
    temp.push("No");
    break;
  } else {
    temp.push("Yes");
    break;
  }
}

这个逻辑会遍历到第一个数字,如果它的重复次数不在3-4之间,就直接push"No"并终止循环,完全忽略了后面的数字。比如第一个手机号98887432里,第一个被遍历到的数字是2(数字键会按升序排列),它的重复次数是1,满足<3,所以直接push"No",根本没检查到数字8的重复次数是3。

正确的逻辑应该是:先默认假设结果是"No",然后遍历所有数字,如果发现有一个数字的重复次数在3-4之间,就把结果改成"Yes"并终止遍历;遍历结束后再把结果push到temp里。

比如:

let result = "No";
for (const num in tempObj) {
  if (tempObj[num] >= 3 && tempObj[num] <= 4) {
    result = "Yes";
    break; // 找到符合条件的就不用继续遍历了
  }
}
temp.push(result);

问题3:手机号长度判断后的break逻辑错误(次要)

你现在的代码里,如果手机号长度超过10,会执行temp.push("No"); break;,这里的break会直接跳出整个i循环,导致后面的手机号都不会被处理。比如如果第一个手机号长度超标,第二个手机号就完全不会被检查。

应该把break改成continue,这样只会跳过当前手机号的处理,继续处理下一个:

if (el.length > 10) {
  temp.push("No");
  continue; // 跳过当前手机号,处理下一个
}

修正后的完整代码

把这些问题都修复后,代码应该是这样的:

function yOrN(phone) {
  const temp = [];
  for (let i = 0; i < phone.length; i++) {
    const el = String(phone[i]);
    if (el.length > 10) {
      temp.push("No");
      continue;
    }
    let tempObj = {};
    for (let j = 0; j < el.length; j++) {
      const em = el[j];
      // 正确的计数逻辑
      tempObj[em] = (tempObj[em] || 0) + 1;
    }
    let result = "No";
    for (const num in tempObj) {
      if (tempObj[num] >= 3 && tempObj[num] <= 4) {
        result = "Yes";
        break;
      }
    }
    temp.push(result);
  }
  return temp;
}

console.log(yOrN([98887432, 12345890])); // 输出 ["Yes", "No"]

现在运行这段代码,就能得到你预期的["Yes", "No"]啦!

备注:内容来源于stack exchange,提问作者Bagus

火山引擎 最新活动