零数组问题:解析Codewars题解JavaScript代码的执行逻辑
题目:Zero-Plentiful数组判断
题目描述
若一个数组包含多组连续的零,且每组零的长度至少为4,则称该数组为zero-plentiful(多零数组)。你的任务是:若给定数组为多零数组,返回其中零序列的数量;否则返回0。
示例
[0, 0, 0, 0, 0, 1]→ 1
一组长度为5的零(≥4),因此结果为1[0, 0, 0, 0, 1, 0, 0, 0, 0]→ 2
两组长度为4的零(≥4),因此结果为2[0, 0, 0, 0, 1, 0]→ 0
一组长度为4的零和一组长度为1的零(<4),要求每组零序列长度至少为4,因此结果为0[0, 0, 0, 1, 0, 0]→ 0
一组长度为3的零(<4)和一组长度为2的零(<4)[1, 2, 3, 4, 5]→ 0
无零元素[]→ 0
无零元素
待分析代码
function zeroPlentiful(arr) { let counter = []; let index = 0; arr.forEach((num, idx) => { if (num === 0) { counter[index] = counter[index] ? counter[index] + 1 : 1; } else { index = counter.length; } }); return counter.every(item => item >= 4) ? counter.length : 0; }
代码逐行执行逻辑讲解
1. 初始化变量
let counter = []; let index = 0;
counter是数组,用来记录每一段连续零序列的长度。比如两段连续零,counter就会有两个元素,分别对应两段零的长度。index标记当前统计的零序列在counter中的位置,初始值为0,默认先统计第一段零序列。
2. 遍历输入数组(forEach循环)
arr.forEach((num, idx) => { // 循环体内容 });
遍历输入数组的每个元素,num是当前元素值,idx是当前元素索引(这段代码没用到idx)。
遇到元素为0时:
if (num === 0) { counter[index] = counter[index] ? counter[index] + 1 : 1; }
- 这段代码用来累加当前零序列的长度:
- 如果
counter[index]已有值(说明之前已经统计过这段零序列里的零),就把它加1; - 如果
counter[index]无值(说明是这段零序列的第一个零),就把它设为1。
- 如果
比如第一次遇到0时,counter[0]不存在,赋值为1;第二次遇到0时,counter[0]变为2,直到遇到非0元素,这段零的长度就存在counter[0]里。
遇到元素不为0时:
else { index = counter.length; }
- 这段代码用来切换到下一段零序列的统计位置:
counter.length是当前已统计完的零序列数量,把index设为这个值,意味着下一次遇到0时,会在counter的新索引位置开始统计新的零序列长度。
比如已经统计完一段零,counter长度是1,index就会被设为1,下一次遇到0时,就往counter[1]里累加长度,对应第二段零序列。
3. 最终判断并返回结果
return counter.every(item => item >= 4) ? counter.length : 0;
counter.every(item => item >=4)检查counter里的每一个元素(每段零序列的长度)是否都≥4:- 如果所有零序列长度都满足≥4,说明是zero-plentiful数组,返回
counter.length(零序列的数量); - 只要有任何一段零序列长度小于4,或者没有零序列(
counter为空),就返回0。
- 如果所有零序列长度都满足≥4,说明是zero-plentiful数组,返回
对应示例的情况:
[0,0,0,0,0,1]:counter最终是[5],every检查通过,返回1;[0,0,0,0,1,0,0,0,0]:counter最终是[4,4],every检查通过,返回2;[0,0,0,0,1,0]:counter最终是[4,1],every检查发现1<4,返回0;[]:counter是空数组,every对空数组返回true,但counter.length为0,返回0;[1,2,3,4,5]:counter是空数组,返回0。
内容的提问来源于stack exchange,提问作者Jeffrey Ti
相关产品推荐
相关产品推荐

