javascript - Javascript:使用 groupBy 将对象列表转换为嵌套对象列表
问题描述
这是我正在使用的 JavaScript 对象的列表:
var filtered = [
{'faculty': 'Faculty of Sciences',
'degree': 'bachelor',
'majorName': 'Computer Science'},
{'faculty': 'Faculty of Sciences',
'degree': 'bachelor',
'majorName': 'Business Computing'},
{'faculty': 'Faculty of Sciences',
'degree': 'masters',
'majorName': 'Computer Science'},
{'faculty': 'Faculty of Sciences',
'degree': 'masters',
'majorName': 'Business Computing'},
{'faculty': 'School of Arts',
'degree': 'bachelor',
'majorName': 'Graphic Design'},
{'faculty': 'School of Arts',
'degree': 'bachelor',
'majorName': 'Media and Communication'},
{'faculty': 'School of Arts',
'degree': 'masters',
'majorName': 'Musicology'},
{'faculty': 'School of Arts',
'degree': 'masters',
'majorName': 'Media'}]
我想通过对教师和学位进行分组,将其转换为嵌套对象列表。
请运行它以查看我当前的结果是什么:
var filtered = [{
'faculty': 'Faculty of Sciences',
'degree': 'bachelor',
'majorName': 'Computer Science'
},
{
'faculty': 'Faculty of Sciences',
'degree': 'bachelor',
'majorName': 'Business Computing'
},
{
'faculty': 'Faculty of Sciences',
'degree': 'masters',
'majorName': 'Computer Science'
},
{
'faculty': 'Faculty of Sciences',
'degree': 'masters',
'majorName': 'Business Computing'
},
{
'faculty': 'School of Arts',
'degree': 'bachelor',
'majorName': 'Graphic Design'
},
{
'faculty': 'School of Arts',
'degree': 'bachelor',
'majorName': 'Media and Communication'
},
{
'faculty': 'School of Arts',
'degree': 'masters',
'majorName': 'Musicology'
},
{
'faculty': 'School of Arts',
'degree': 'masters',
'majorName': 'Media'
}
]
var grouped = _.mapValues(_.groupBy(filtered, 'faculty'),
flist => flist.map(filtered => _.omit(filtered, 'faculty')));
_.forEach(grouped, function(value, key) {
grouped[key] = _.groupBy(grouped[key], function(item) {
return item.degree;
});
});
console.log(grouped);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"></script>
我怎样才能省略留下的“度”属性?并将“majorName”属性的值保留在属于生成的学位属性的列表中?
最终结果可能是这样的:
{
"Faculty of Sciences": {
"bachelor": ["Computer Science", "Business Computing"],
"masters": ["Computer Science", "Business Computing"]
},
"School of Arts": {
"bachelor": ["Graphic Design", "Media and Communication"],
"masters": ["Musicology", "Media"]
}
}
谢谢 :)
解决方案
使用reduce()
、解构和逻辑无效赋值 (??=)为您提供了一个简洁的香草解决方案。
const
filtered = [{ 'faculty': 'Faculty of Sciences', 'degree': 'bachelor', 'majorName': 'Computer Science' }, { 'faculty': 'Faculty of Sciences', 'degree': 'bachelor', 'majorName': 'Business Computing' }, { 'faculty': 'Faculty of Sciences', 'degree': 'masters', 'majorName': 'Computer Science' }, { 'faculty': 'Faculty of Sciences', 'degree': 'masters', 'majorName': 'Business Computing' }, { 'faculty': 'School of Arts', 'degree': 'bachelor', 'majorName': 'Graphic Design' }, { 'faculty': 'School of Arts', 'degree': 'bachelor', 'majorName': 'Media and Communication' }, { 'faculty': 'School of Arts', 'degree': 'masters', 'majorName': 'Musicology' }, { 'faculty': 'School of Arts', 'degree': 'masters', 'majorName': 'Media' }],
groupedObjs = filtered.reduce((a, { faculty, degree, ...rest }) =>
(((a[faculty] ??= { [degree]: [] })[degree] ??= []).push({ ...rest }), a), {}),
groupedStrings = filtered.reduce((a, { faculty, degree, majorName }) =>
(((a[faculty] ??= { [degree]: [] })[degree] ??= []).push(majorName), a), {});
console.log(groupedStrings);
console.log(groupedObjs);
.as-console-wrapper { max-height: 100% !important; top: 0; }
或没有逻辑无效分配...
const
filtered = [{ 'faculty': 'Faculty of Sciences', 'degree': 'bachelor', 'majorName': 'Computer Science' }, { 'faculty': 'Faculty of Sciences', 'degree': 'bachelor', 'majorName': 'Business Computing' }, { 'faculty': 'Faculty of Sciences', 'degree': 'masters', 'majorName': 'Computer Science' }, { 'faculty': 'Faculty of Sciences', 'degree': 'masters', 'majorName': 'Business Computing' }, { 'faculty': 'School of Arts', 'degree': 'bachelor', 'majorName': 'Graphic Design' }, { 'faculty': 'School of Arts', 'degree': 'bachelor', 'majorName': 'Media and Communication' }, { 'faculty': 'School of Arts', 'degree': 'masters', 'majorName': 'Musicology' }, { 'faculty': 'School of Arts', 'degree': 'masters', 'majorName': 'Media' }],
groupedObjs = filtered.reduce((a, { faculty, degree, ...rest }) => {
a[faculty] = a[faculty] || { [degree]: [] };
(a[faculty][degree] = a[faculty][degree] || []).push({ ...rest });
return a
}, {}),
groupedStrings = filtered.reduce((a, { faculty, degree, majorName }) => {
a[faculty] = a[faculty] || { [degree]: [] };
(a[faculty][degree] = a[faculty][degree] || []).push(majorName);
return a
}, {});
console.log(groupedStrings);
console.log(groupedObjs);
.as-console-wrapper { max-height: 100% !important; top: 0; }
推荐阅读
- html - 如何以角度放置微调器
- redux - Redux-Toolkit:如何处理具有复合键的实体?
- c# - 构建在本地通过但在詹金斯服务器上失败,system.servicemodel.faultexception 无法加载文件或程序集和 system.timeoutexception
- unix - awk 输出到指定的列数
- firebase - Flutter future builder完成后什么都不显示-firestore
- reactjs - 如何使用打字稿将多个参考传递给forwardRef
- visual-studio-code - 保存编辑器布局
- r - 如何在 R 中抓取 PDF 的所有页面?
- html - 为什么我的 div 没有出现在我的主 div 中?
- angular - How to use button value for filter pipes in Angular