如何拆分对象数组为多个子数组,过滤重复值并格式化为name/label结构
实现方案
原生JS版本(无需第三方依赖)
直接在reduce逻辑里同时完成分组、格式转换、去重三个需求:
var fullData = [{foo1: 'bar1', foo2: 'bar2', foo3: 'bar3'}, {foo1: 'bar4', foo2: 'bar5', foo3: 'bar6'}, {foo1: 'bar7', foo2: 'bar8', foo3: 'bar6'}] const result = fullData.reduce((acc, cur) => { Object.entries(cur).forEach(([key, val]) => { // 初始化对应key的存储数组 acc[key] = acc[key] || [] // 检查重复,避免重复插入 const isDuplicate = acc[key].some(item => item.name === val) if (!isDuplicate) { acc[key].push({ name: val, label: val }) } }) return acc }, Object.create(null)) // 按顺序输出三个数组的示例 const [foo1Arr, foo2Arr, foo3Arr] = Object.values(result)
执行后返回结果:
foo1Arr为[{name: 'bar1', label: 'bar1'}, {name: 'bar4', label: 'bar4'}, {name: 'bar7', label: 'bar7'}]foo2Arr为[{name: 'bar2', label: 'bar2'}, {name: 'bar5', label: 'bar5'}, {name: 'bar8', label: 'bar8'}]foo3Arr为[{name: 'bar3', label: 'bar3'}, {name: 'bar6', label: 'bar6'}]
Lodash简化版本
如果已经在项目中引入了lodash,可以用_.uniqBy简化去重逻辑:
const _ = require('lodash') const result = fullData.reduce((acc, cur) => { Object.entries(cur).forEach(([key, val]) => { acc[key] = acc[key] || [] acc[key].push({ name: val, label: val }) }) return acc }, Object.create(null)) // 统一对每个分组去重 Object.keys(result).forEach(key => { result[key] = _.uniqBy(result[key], 'name') }) const [foo1Arr, foo2Arr, foo3Arr] = Object.values(result)
原reduce代码逻辑说明
你之前找到的代码只做了按key分组收集原始值的工作:
- 以空对象为初始累计器,遍历原数组的每个对象
- 取出当前对象的所有键值对,对每个键,在累计器中初始化对应空数组,把值推入数组
- 最终返回按键分组的原始值集合,没有做格式转换和去重,补充对应的逻辑即可完成需求。
内容的提问来源于stack exchange,提问作者profiter
相关产品推荐
相关产品推荐

