如何根据对象数组key存在性及数组长度奇偶处理值生成目标数组
数组转换逻辑修正与问题解决
原始数据
[ { "time": 0 }, { "endTime": 4.5, "time": 4 }, { "time": 5 }, { "endTime": 7, "time": 6 }, { "endTime": 10, "time": 8 }, { "endTime": 15, "time": 11 } ]
预期输出
result : [0, 4.5, 5, 7, 8, 10, 11, 15]
转换规则
- 仅包含
time字段的对象:将time值推入结果数组的奇数索引位置(如示例中的0、5) - 同时包含
time和endTime字段的对象:- 若结果数组当前长度为奇数:仅推入
endTime值(如示例中的4.5、7) - 若结果数组当前长度为偶数:按顺序推入
time和endTime值(如示例中的8、10,11、15)
- 若结果数组当前长度为奇数:仅推入
错误代码
let arrayOfSliderStartEndTime = arr.reduce((pv, cv, i) => { if(!"endTime" in cv) pv.res.push(cv.time) else if("endTime" in cv) { if(pv.res.length%2 != 0) pv.res.push(cv.time) pv.res.push(cv.endTime) }
问题分析与修正代码
你的代码存在两个核心问题:
- 未给
reduce指定初始值,导致pv.res会抛出未定义的错误 - 处理带
endTime的对象时逻辑完全颠倒:规则要求数组长度为奇数时推入endTime,你却推入了time;长度为偶数时需要按顺序推入两个值,你的代码逻辑未覆盖该场景,而是直接追加endTime,导致结果不符合预期
以下是修正后的完整代码:
const arr = [ { "time": 0 }, { "endTime": 4.5, "time": 4 }, { "time": 5 }, { "endTime": 7, "time": 6 }, { "endTime": 10, "time": 8 }, { "endTime": 15, "time": 11 } ]; const result = arr.reduce((res, cv) => { // 处理仅含time字段的对象 if (!("endTime" in cv)) { res.push(cv.time); } else { // 处理同时含time和endTime的对象 if (res.length % 2 !== 0) { // 当前数组长度为奇数,仅推入endTime res.push(cv.endTime); } else { // 当前数组长度为偶数,按顺序推入time和endTime res.push(cv.time); res.push(cv.endTime); } } return res; }, []); // 必须传入初始空数组作为reduce的初始值 console.log("result :", result); // 输出:result : [0, 4.5, 5, 7, 8, 10, 11, 15]
逻辑验证
我们逐步骤验证转换过程,确保符合规则:
- 第一个对象
{"time":0}:仅含time,推入数组 →[0](长度1,奇数) - 第二个对象
{"endTime":4.5,"time":4}:数组长度为奇数,推endTime →[0,4.5](长度2,偶数) - 第三个对象
{"time":5}:仅含time,推入 →[0,4.5,5](长度3,奇数) - 第四个对象
{"endTime":7,"time":6}:数组长度为奇数,推endTime →[0,4.5,5,7](长度4,偶数) - 第五个对象
{"endTime":10,"time":8}:数组长度为偶数,推time和endTime →[0,4.5,5,7,8,10](长度6,偶数) - 第六个对象
{"endTime":15,"time":11}:数组长度为偶数,推time和endTime →[0,4.5,5,7,8,10,11,15](最终结果)
完全匹配预期输出。
内容的提问来源于stack exchange,提问作者Vikas Acharya
相关产品推荐
相关产品推荐

