Created
January 29, 2024 19:13
-
-
Save librz/2b9e0f7d4fdcaa67f866793cc1ca0f9c to your computer and use it in GitHub Desktop.
用 object 的 key 对 array of objects 进行分组
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const list = [ | |
{ province: '天津', city: '南开', district: '三马路' }, | |
{ | |
province: '天津', | |
city: '南开', | |
district: '四马路' | |
}, | |
{ | |
province: '天津', | |
city: '河西', | |
district: '二马路' | |
}, | |
{ | |
province: '江苏省', | |
city: '无锡市', | |
district: '新吴区' | |
}, | |
{ | |
province: '江苏省', | |
city: '无锡市', | |
district: '无锡经济开发区' | |
} | |
] | |
function omitKeys(obj, keys) { | |
const cloned = JSON.parse(JSON.stringify(obj)); | |
keys.forEach(key => { | |
delete cloned[key]; | |
}) | |
return cloned; | |
} | |
function liftPropsAsKeys(obj, props) { | |
if (props.length < 1) { | |
return obj; | |
} | |
const [prop, ...restProps]= props; | |
if (props.length === 1) { | |
return { | |
[obj[prop]]: omitKeys(obj, [prop]) | |
} | |
} | |
return { | |
[obj[prop]]: liftPropsAsKeys(omitKeys(obj, [prop]), restProps) | |
} | |
} | |
// const obj = { age: 10, name: 'Jason', address: 'Baker Street', sex: 'Male' } | |
// const lifted = liftPropsAsKeys(obj, ['age', 'name', 'sex']); | |
// console.log(JSON.stringify(lifted, null, 2)) | |
function groupByKeys(list, props) { | |
if (props.length === 0) { | |
return list; | |
} | |
const result = []; | |
const [prop, ...restProps] = props; | |
list.forEach(li => { | |
const lifted = liftPropsAsKeys(li, [prop]); | |
const key = li[prop]; | |
const value = lifted[key]; | |
// 特殊处理:如果 key 对应的 value 是空对象的话,直接使用 key 作为 value | |
if (Object.keys(value).length === 0) { | |
if (!result.includes(key)) { | |
result.push(key) | |
} | |
return; | |
} | |
// 普通 group by 处理 | |
lifted[key] = [value]; | |
const itemWithSameKey = result.find(it => Object.keys(it).includes(key)); | |
if (itemWithSameKey) { | |
itemWithSameKey[key].push(value); | |
} else { | |
result.push(lifted) | |
} | |
}) | |
result.forEach(li => { | |
Object.keys(li).forEach(key => { | |
li[key] = groupByKeys(li[key], restProps) | |
}) | |
}) | |
return result; | |
} | |
const groupedList = groupByKeys(list, ['province', 'city', 'district']); | |
console.log(JSON.stringify(groupedList, null, 2)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment