Javascript,按属性提取和组织对象数组

时间:2016-10-01 22:27:33

标签: javascript vue.js

简而言之,我想创建一个通用的方法“组织”来解决这个问题:

[
    { name: 'band1', type: 'concert', subtype: 'rock' },
    { name: 'band2', type: 'concert', subtype: 'jazz' },
    { name: 'band3', type: 'concert', subtype: 'jazz' },
    { name: 'fun1', type: 'festival', subtype: 'beer' },
    { name: 'fun2', type: 'festival', subtype: 'food' },
]

进入这个:

{
    'concert': {
      'rock': [
        { name: 'band1', type: 'concert', subtype: 'rock' },
      ],
      'jazz': [
        { name: 'band2', type: 'concert', subtype: 'jazz' },
        { name: 'band3', type: 'concert', subtype: 'jazz' }
      ]
    },
    'festival': {
      'beer': [
        { name: 'fun1', type: 'festival', subtype: 'beer' },
      ],
      'food': [
        { name: 'fun2', type: 'festival', subtype: 'food' },
      ]
    }
}

来自签名:

organize(events, ['type', 'subtype']);

我想要这样做的原因是有一个简单的嵌套for循环来显示数据。如果您熟悉Vue.js,它将如下所示:

<div v-for="(type, subtypes) in organize(events, ['type', 'subtype'])">
  <h1>{{ type }}</h1>
  <div v-for="(subtype, events) in subtypes">
    <h2>{{ subtype }}</h2>
    <div v-for="event in events">
      <h3>{{ event.name }}</h3>
    </div>
  </div>
</div>

对我而言,这是一项大脑弯曲的运动。我认为递归和map filter reduce的某种组合已经成熟,但我花了太多时间试图想出一个解决方案,而是写了一些非常丑陋的代码来完成基本上是一样的。也有可能我不知道javascript的一些有用功能可以帮助我做到这一点....

建议或指导将不胜感激,但这不是一个紧迫的问题。我认为使用通用方法来组织数组非常有用。

2 个答案:

答案 0 :(得分:2)

我认为这可能是organize的正确实现:

&#13;
&#13;
function organize(rows, groupBy) {
    var last = groupBy.length - 1;
    return rows.reduce ( (res, obj) => {
        groupBy.reduce( (res, grp, i) => 
            res[obj[grp]] || (res[obj[grp]] = i == last ? [] : {}), res).push(obj);
        return res;
    }, {});
}

var events = [
    { name: 'band1', type: 'concert', subtype: 'rock' },
    { name: 'band2', type: 'concert', subtype: 'jazz' },
    { name: 'band3', type: 'concert', subtype: 'jazz' },
    { name: 'fun1', type: 'festival', subtype: 'beer' },
    { name: 'fun2', type: 'festival', subtype: 'food' },
];

var res = organize(events, ['type','subtype']);

console.log(res);
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以使用_.groupBy()库中的LoDash

&#13;
&#13;
var source = [
  { name: 'band1', type: 'concert', subtype: 'rock' },
  { name: 'band2', type: 'concert', subtype: 'jazz' },
  { name: 'band3', type: 'concert', subtype: 'jazz' },
  { name: 'fun1', type: 'festival', subtype: 'beer' },
  { name: 'fun2', type: 'festival', subtype: 'food' },
];
  
var groupedByType = _.groupBy(source, 'type');
console.log(groupedByType);
  
var groupedByTypeAndSubtype = {};
for (var i in groupedByType) {
  groupedByTypeAndSubtype[i] = _.groupBy(groupedByType[i], 'subtype');
}

console.log(groupedByTypeAndSubtype);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.2/lodash.js"></script>
&#13;
&#13;
&#13;