Skip to content

Instantly share code, notes, and snippets.

@librz
Created January 29, 2024 19:13
Show Gist options
  • Save librz/2b9e0f7d4fdcaa67f866793cc1ca0f9c to your computer and use it in GitHub Desktop.
Save librz/2b9e0f7d4fdcaa67f866793cc1ca0f9c to your computer and use it in GitHub Desktop.
用 object 的 key 对 array of objects 进行分组
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