【问题标题】:Group array of object nesting some of the keys with specific names嵌套一些具有特定名称的键的对象组数组
【发布时间】:2021-07-03 14:40:25
【问题描述】:

我有这个对象数组,我需要对其进行修改以使其更容易渲染。

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,但它并不能完全满足我的要求。 关于如何处理它的任何想法?

非常感谢!!

【问题讨论】:

标签: javascript arrays object nested grouping


【解决方案1】:

这可以通过_.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>

【讨论】:

    【解决方案2】:

    你可以在没有额外库的情况下使用一个对象。

    该对象包含一个属性_,它保存给定嵌套组的嵌套数组。

    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 解决方案也很完美,现在唯一的疑问是哪个更有效......
    • @JCGarcia 我敢打赌这个,比使用 lodash 更原生。 @Nina,Map 比使用简单对象 {} 更好吗?顺便说一句,非常好的解决方案!
    • @sjahan,使用 for 循环对象可能更快。
    • 我个人总是会听从 Nina 更好的知识 ;) 除了这不会对部分进行第二级聚合
    • @Jamiec,抱歉,没有看到嵌套分组。
    猜你喜欢
    • 2022-01-02
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 2017-05-14
    • 2021-10-14
    相关资源
    最近更新 更多