判断题目必填项是否为空
originalQuestions
数组存放着访谈题目列表(目前共有 18 道),数据格式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| var originalQuestions = [ { content: "请简单介绍一下您的经历(包括部门、岗位、司龄、曾任职的公司和岗位等)?", id: "f9912584095a694c9f9882518c4e9da350b6", choices: [], isShow: 1, maxChoices: 0, minChoices: 0, number: 1, required: true, type: 2, }, { content: "您是否是部门负责人?", id: "9d5a5f98799b0743d608b7f2eb1d0e338b84", choices: [ { content: "是", id: "1b5366a873ddaf43a08b4fdfef9e133d72d2", isExclude: 0, jumpNumber: 7, number: 1, required: false, type: 0, }, { content: "否", id: "6c8c368b15998e4798d89f47d35127559631", isExclude: 0, jumpNumber: 8, number: 2, required: false, type: 0, } ], isShow: 1, maxChoices: 0, minChoices: 0, number: 6, required: true, type: 0, }];
|
访谈题目分为两种:一种是简答题,另一种是判断题。在这里需要根据题目的 required 属性来确定题目是否必填。
通过请求处理得到的响应数据为一个数组,数组当中的每个对象对应着一个用户的访谈填写详情。对象中的前四个属性是用户基本信息,并非用户访谈题目的填写答案,最后五个属性也是如此,只有中间那部分才是用户作答的完整信息,即 list[userIndex][4]
才是用户填写的第一道题的答案。
另外,用户也并非每道题都有作答。例如,当用户没有作答第二道题,那么对象就不会存在 “5” 属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| var list = [ { "0": "肖 AA", "1": "前端", "2": "前端", "3": "高", "4": 222, "7": 2222, "9": "是", "10": 333, "name": "肖 AA", "department": "前端", "job": "前端", "level": "高", "_XID": "row_86" }, { "0": "肖 BB", "1": "前端", "2": "前端", "3": "高", "4": 222, "5": 2222, "6": 2222, "7": 2222, "8": 2222, "9": "是", "10": 333, "name": "肖 BB", "department": "前端", "job": "前端", "level": "高", "_XID": "row_26" }];
|
在这里,我们需要对用户作答情况进行处理,检测是否存在用户没有作答必填项。一旦发现存在,直接返回该用户的 index 以及未作答题目的序号。
① 检测单个用户
在这里先只对一个用户对象进行检测,即:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var obj = { "0": "肖 AA", "1": "前端", "2": "前端", "3": "高", "4": 222, "7": 2222, "9": "是", "10": 333, "name": "肖 AA", "department": "前端", "job": "前端", "level": "高", "_XID": "row_86" }
|
至于要从用户答案还是题目列表开始遍历,很显然,因为要判断用户有无漏答题目,所以应从 originalQuestions 开始。
第一版( forEach
实现)
实现思路
通过 forEach
来遍历题目列表,当题目的 required 为 true 且用户对应题目的作答情况为空时,则标记好信息后直接 return 跳出循环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var isFalse = false; var pos = -1;
function determine0(obj) { originalQuestions.forEach((item, index)=> { if(item.required && !obj[String(index + 4)]) { this.isFalse = true; this.pos = index; console.log(`pos:${index}`); return; } }) } determine0(obj);
|
输出结果
1 2 3 4 5
| pos:1 pos:2 pos:4 pos:7 pos:8
|
存在缺陷
- 打印输出多次,这说明 return 并没有跳出循环。查阅资料后发现,
forEach
循环不能被 return 终止,其作用和 for 循环中的 continue 相似,只是跳出当前循环,并继续执行之后的循环。同样,在 forEach
中也不能使用 break、continue 来跳出循环。
第二版( findIndex
实现)
实现思路
数组的 findIndex
方法会根据 return 返回的条件进行遍历查找,一旦发现数组中有匹配的元素,就直接返回该元素的 index。
1 2 3 4 5 6 7 8 9 10 11 12 13
| function determine1(obj) { this.pos = originalQuestions.findIndex((item, index)=> { if(item.required && !obj[String(index + 4)]) { console.log(`pos:${index}`); } return item.required && !obj[String(index + 4)]; }) if(this.pos !== -1) { this.isFalse = true; } } determine1(obj);
|
输出结果
② 检测所有用户
当检测所有用户时,所需要采用的策略与检测单个用户时大有不同。仍旧是先遍历谁的问题,这次该从用户列表还是从题目列表开始遍历?这里采用的是,先从题目列表中遍历。当抽出一道题时,再从用户列表中依次抽取用户来比对是否作答该题目。
基础版
实现思路
因为要对所有用户依次进行题目列表的遍历,但真正需要遍历的题目只有必选题,所以为了提高效率,需要先通过数组的 filter 方法把题目列表筛选成只含有必答题的题目列表。
得到精简后的题目列表后,通过使用数组的 some 方法来判断是否存在用户未作答题目。当存在时,some 方法的返回结果为 true,否则返回 false。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| var row = -1; var column = -1;
function determineAll0(list) { var newQuestions = questions.filter(item => item.required); var a; var result; return newQuestions.some(item => { for(a=0; a<list.length; a++) { result = list[a][String(item.number + 4)]; if(!result) { this.row = a; this.column = item.number; console.log(`row: ${this.row}, col:${this.column}`); } return !result; } }) } this.isFalse = determineAll0(originalList);
|
输出结果
存在缺陷
简化版
基础的 for 循环操作有些繁琐,数组的 filter 和 some 方法可以合并。对代码进行简化如下。
1 2 3 4 5 6 7 8
| function determineAll1(list) { return questions.filter(f => f.required).some(question => { this.column = question.number this.row = list.findIndex(user => !user[String(question.number + 4)]) return this.row !== -1; }) }
|
娱乐版
经过试验,最后将代码化简至 3 行。
1 2 3 4
| function determineAll2(list) { return questions.filter(f => f.required).some(s =>(this.row = list.findIndex(i => !i[(this.column = s.number) + 4])) + 1) }
|