简而言之,我想创建一个通用方法“组织”来转换它:
[
{ 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 的一些有用的特性可以帮助我做到这一点....
建议或指导将不胜感激,但这不是紧迫的事情。我只是认为有一个通用的方法来组织这样的数组真的很有用。
最佳答案
我认为这可能是 organize
的正确实现:
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);
关于Javascript,按属性提取和组织对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39812038/