如何将对象数组中的内部子数组移至外层数组(附代码示例)
问题:拆分对象数组中的嵌套sites元素并避免修改原数据
需求说明
将对象数组中每个元素的sites子数组内的对象移至外层数组,同时把原元素的sites设为空数组。
原始数据示例
const data = [ {id:3333, name:'a', sites: []}, {id:2343, name:'b', sites: [ {id: 3322, name: 'f', sites: null}, {id: 3211, name: 'v', sites: null}, ]}, {id:4444, name:'c', sites: []}, ]
期望结果
const newData = [ {id:3333, name:'a', sites: []}, {id:2343, name:'b', sites: []}, {id: 3322, name: 'f', sites: null}, {id: 3211, name: 'v', sites: null}, {id:4444, name:'c', sites: []}, ]
现有代码的问题
你当前的实现存在两个问题:
- 没有将原元素的
sites设为空数组,不符合需求; - 直接将原对象push到新数组,后续修改新数组内的对象会同步影响原数据(引用传递导致)。
优化方案
基础实现(避免修改原数据)
利用flatMap一步完成遍历和数组展开,同时通过浅拷贝原对象隔离原数据:
const newData: ISite[] = data.flatMap(site => { // 浅拷贝原对象,切断与原数据的引用关联 const copiedSite = { ...site }; // 按需求将拷贝后的对象sites设为空数组 copiedSite.sites = []; // 返回当前对象 + sites子数组里的元素,flatMap会自动合并成一维数组 return [copiedSite, ...(site.sites || [])]; });
兼容sites为null的情况
如果原数据中sites可能为null,可以加类型判断避免报错:
const newData: ISite[] = data.flatMap(site => { const copiedSite = { ...site }; copiedSite.sites = []; // 只当sites是数组时才展开,否则展开空数组 const nestedSites = Array.isArray(site.sites) ? site.sites : []; return [copiedSite, ...nestedSites]; });
方案优势
- 代码更简洁:用
flatMap替代forEach+手动push,逻辑更紧凑; - 完全隔离原数据:通过浅拷贝原对象,不会修改原始数组里的任何内容;
- 精准满足需求:自动将原元素的
sites设为空数组,同时把嵌套元素移到外层。
内容的提问来源于stack exchange,提问作者Amelia W
相关产品推荐
相关产品推荐

