如何将含数组值的对象转换为提取指定字段的字符串数组?
从值为数组的对象中提取所有元素的name属性生成字符串数组
需求背景
有一个属性值均为数组的对象,每个数组元素都是带name属性的对象:
const testObj = { first: [ { name: 'Den' }, { name: 'Ben' } ], second: [ { name: 'Ken' } ] }
需要提取所有数组元素的name值,生成统一的字符串数组,预期结果:
['Den', 'Ben', 'Ken']
你已经通过以下代码实现需求:
const res = Object.keys(testObj).map(key=>{ return testObj[key].map(el=>el.name) }).flat(1)
几个更优的替代方案
1. Object.values + 展开运算符 + concat一步合并数组
直接获取对象的所有值数组,合并后统一提取name,减少一次中间数组生成:
const res = [].concat(...Object.values(testObj)).map(item => item.name)
逻辑直观:先用Object.values拿到所有子数组,通过展开运算符将子数组作为concat的参数合并成大数组,最后提取每个元素的name。
2. 用flatMap简化map+flat操作
flatMap内置了map后执行flat(1)的逻辑,代码更简洁,语义更明确:
const res = Object.values(testObj).flatMap(arr => arr.map(item => item.name))
相比原方案,省去了单独调用flat的步骤,将映射与扁平化合并为一步。
3. 用reduce灵活累加结果
如果后续需要对name做额外处理(比如去重、过滤空值),reduce的灵活性更高:
const res = Object.values(testObj).reduce((result, currentArr) => { // 可添加额外逻辑,比如过滤空name const validNames = currentArr.map(item => item.name).filter(Boolean) result.push(...validNames) return result }, [])
无额外处理时也可简化为:
const res = Object.values(testObj).reduce((acc, arr) => acc.concat(arr.map(item => item.name)), [])
方案对比
- 原方案:逻辑清晰,但两次
map生成二维数组后再flat,多了一次扁平化开销。 concat+展开运算符:可读性强,合并与提取步骤分离,性能与flatMap相近。flatMap:最简洁的写法,现代浏览器均支持,推荐日常使用。reduce:适合需要额外处理逻辑的场景,灵活性拉满。
内容的提问来源于stack exchange,提问作者DevOverflow
相关产品推荐
相关产品推荐

