故事背景: 接到一个自定义多级下拉的需求, 功能已经完成,但是在提交数据时测试提出要做非空校验, 意思就是如果有层级存在空字段, 需要跳到该层级并给出提示, 不用递归实现的话, 三次 for 循环还是挺好实现的, 但是作为一个有追求的 coder, 我们最终还是通过递归的方式来实现的,毕竟 leetcode 也刷了几十道了, 也该考验一下刷题的效果了.
效果如下:
Kapture 2022-04-10 at 18.44.13.gif首先我们来看下 json-tree 格式
/**
*@desc value 就是表单绑定的值
*/
[{
"value":"0",
"child":[{
"value":"0-0",
"child":[{
"value":"",
"nodeId":"c0",
"pnodeId":"b0",
"uniqueness":"0.14658520948272225"
}],
"nodeId":"b0",
"pnodeId":"a0",
"uniqueness":"0.49521203933283897"
}],
"nodeId":"a0",
"pnodeId":0,
"uniqueness":"0.6101862372680027"
},
{
"value":"1",
"child":[{
"value":"1-1",
"child":[],
"nodeId":"b0",
"pnodeId":"a1",
"uniqueness":"0.9895125407132053"
},
{
"value":"",
"child":[],
"nodeId":"b1",
"pnodeId":"a1",
"uniqueness":"0.25298626352369147"
}],
"nodeId":"a1",
"pnodeId":0
}]
写的有点糙,请不要介意,算法如下:
const indexs = [] // 用户存储 index 路劲
let flag = true // 申明一个全局变量,可以在闭包中可以访问, 从而使 for 可以跳出来
function formValidation(arr, l = 0) {
for (let i = 0; i < arr.length; i++) {
if (!flag) { // 跳出 for 循环的标识, 如果 value 为空, 深度向上遍历跳出 for 循环
break
}
if (l === 0) { // 每一级的路径我们是通过 Array 形式 存储的, 如果这里不清空, 校验下一列的时候还会存留上一列的数据
indexs.length = 0 // 这种方式清除 Array, 算是骚操作吧, 但确实优化了判断逻辑
}
indexs[l] = i // 将列的路径存在 array 中
if (!String(arr[i].value).trim()) { // 判断 value 是否为空, 为空就需要跳出 for 循环, 这里用到了闭包, 代码层面看只有一层, 但是实际运行时, 是 for 循环里面嵌套 for 循环的.
indexs.length = l // 将 数组的长度 与 递归的深度保持一致(打个比方: 比如第一层第三级遍历完了, 后面会继续遍历第二级数据, 遍历第二层数据时, 之前的第三级数据我们是要清除的, 所以我们直接通过 array length 来清除)
indexs[l] = i
flag = false
break
}
if (arr[i].child?.length) { // 有子集 递归遍历
formValidation(arr[i].child, l + 1)
}
}
}
网友评论