JavaScript修改二维数组对象属性并保留原结构的实现方法
二维数组复选框选中状态切换实现
需求说明
需要实现复选框选中状态切换逻辑:匹配到目标项时,将该项的selected属性值取反。
待处理数据为二维数组结构:外层数组元素为内层数组,内层数组存储业务对象,对象包含module、selected、name、points属性,其中points本身也是对象数组,结构示例:
[ [ { "module": "string", "selected": false, "name": "title", "points": [{ "category": "category1", "description": "desc1", "provided": "provided1" }, { "category": "category1", "description": "desc", "provided": "something" } ] }, { "module": "string", "selected": false, "name": "title_one", "points": [{ "category": "category1", "description": "desc1", "provided": "provided1" }, { "category": "category1", "description": "desc", "provided": "something" } ] }, ], [...], [...] ]
原有代码问题
原有实现运行后返回的数据多嵌套了一层数组,不符合原始二维结构要求。
原有错误代码:
//checked value is the information of the checkbox and valuesArr is the entire array function toggleCheck(checkedValue, valuesArr) { return { value: valuesArr.map((module, i, ...values) => { return [ ...values, (values[i] = module.map((x, j, ...transObj) => ({ ...transObj, selected: x.name === checkedValue.name ? !values[i][j].selected : values[i][j].selected, }))), ]; }), }; }
错误输出结构:
[ [ [ {}, {}, {} ], [...], [...] ] ]
期望输出结构:
[ [ {}, {}, {} ], [...], [...] ]
错误原因
- 错误使用
Array.map的第三个参数(遍历的完整原数组),通过剩余参数展开后又在外层手动包裹数组、展开参数,直接导致层级嵌套异常 - 内层map时错误将当前遍历的内层数组通过剩余参数展开混入业务对象,会导致对象出现多余的数组索引属性
- 直接对原数组元素做赋值修改,会产生副作用污染原始数据
正确实现代码
function toggleCheck(checkedValue, valuesArr) { return { value: valuesArr.map(innerArray => { return innerArray.map(item => { // 匹配到目标name时翻转selected属性,其余项原样返回 return item.name === checkedValue.name ? { ...item, selected: !item.selected } : item }) }) } }
实现说明
- 完全保留原始二维数组层级,不会出现多余嵌套
- 采用浅拷贝的不可变更新方式,不会修改传入的原始源数组,无副作用
- 业务对象的所有原有属性(
module/points等)都会完整保留,不会出现字段丢失问题 - 逻辑简洁,无多余的展开、赋值操作,不存在隐式的结构篡改问题
内容的提问来源于stack exchange,提问作者CleverlyDone
相关产品推荐
相关产品推荐

