首页 > 解决方案 > 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"]
}
}

谢谢 :)

标签: javascriptjavascript-objects

解决方案


使用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; }


推荐阅读