使用特定名称的键将对象数组分组嵌套

5

我有一个对象数组,需要对其进行修改以便更容易地呈现。

const items = [
  {
    tab: 'Results',
    section: '2017',
    title: 'Full year Results',
    description: 'Something here',
  },
    {
    tab: 'Results',
    section: '2017',
    title: 'Half year Results',
    description: 'Something here',
  },
    {
    tab: 'Reports',
    section: 'Marketing',
    title: 'First Report',
    description: 'Something here',
  },
  ...
];

我正在尝试修改它们,按特定键进行分组。想法是要有这样的输出。您可以看到键的名称可能与项目中实际名称不同。我认为这与以前的帖子有所不同。

const output = [
  {
    tab: 'Results',
    sections: [
      {
         section: '2017',
         items: [ { 'item that belongs here' }, { ... } ],
      },
  },
  {
    tab: 'Reports',
    sections: [
      {
         section: 'Marketing',
         items: [ { ... }, { ... } ],
      },
  },
...
]

我尝试使用lodash.groupby,但它并不能完全满足我的需求。你有任何想法吗?
非常感谢!

你想要按哪个键进行分组? - zabusa
2个回答

5
这可以通过巧妙地结合_.map_.groupBy来实现。

const items = [
  {
    tab: 'Results',
    section: '2017',
    title: 'Full year Results',
    description: 'Something here',
  },
    {
    tab: 'Results',
    section: '2017',
    title: 'Half year Results',
    description: 'Something here',
  },
    {
    tab: 'Reports',
    section: 'Marketing',
    title: 'First Report',
    description: 'Something here',
  }
];

function groupAndMap(items, itemKey, childKey, predic){
    return _.map(_.groupBy(items,itemKey), (obj,key) => ({
        [itemKey]: key,
        [childKey]: (predic && predic(obj)) || obj
    }));
}

var result = groupAndMap(items,"tab","sections", 
                   arr => groupAndMap(arr,"section", "items"));


console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


3
你可以使用一个不需要额外库的对象。
该对象包含一个名为 _ 的属性,它保存给定嵌套组的嵌套数组。

var items = [{ tab: 'Results', section: '2017', title: 'Full year Results', description: 'Something here' }, { tab: 'Results', section: '2017', title: 'Half year Results', description: 'Something here' }, { tab: 'Reports', section: 'Marketing', title: 'First Report', description: 'Something here' }],
    keys = { tab: 'sections', section: 'items' }, // or more if required
    result = [],
    temp = { _: result };

items.forEach(function (object) {
    Object.keys(keys).reduce(function (level, key) {
        if (!level[object[key]]) {
            level[object[key]] = { _: [] };
            level._.push({ [key]: object[key], [keys[key]]: level[object[key]]._ });
        }
        return level[object[key]];
    }, temp)._.push({ title: object.title, description: object.description });
});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


解决方案看起来非常整洁,谢谢! 此外@Jamiec的解决方案完美运行,现在唯一的疑问是哪个更有效率... - JC Garcia
@sjahan,使用for循环可能会使对象更快。 - Nina Scholz
我个人会始终听从Nina更好的知识;)除了这个不对章节进行第二层聚合。 - Jamiec
@Jamiec,抱歉,我没有看到嵌套分组。 - Nina Scholz
@NinaScholz 很好! :) - sjahan
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接