2016-10-01 76 views
1

總之對象的數組,我要創建一個通用方法「組織」關閉此:的Javascript,提取和組織由屬性

[ 
    { 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']); 

我想這樣做的原因是有一個簡單的嵌套循環顯示數據。如果你對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> 

對我來說,這是一個大腦彎曲練習。我認爲遞歸和mapfilterfilterreduce的一些組合已經成熟,但我花了太多時間試圖想出解決方案,而是編寫了一些非常難看的代碼來完成基本相同的事情。這也可能,我不知道一些有用的功能的JavaScript,可以幫助我這樣做...

建議或指導將不勝感激,但它不是一個緊迫的問題。我只是覺得有一個通用的方法來組織數組是非常有用的。

+0

只是一個建議:如果你已經有一個解決方案可行,但你認爲可以進一步優化,你可以在[CodeReview](http://codereview.stackexchange.com)上發佈一個問題;) – Terry

回答

2

我認爲這可能是一個正確實施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);

+0

很好地完成!今晚我沒有時間查看它,但是將您的功能複製並粘貼到我的代碼中就像魅力一樣!更乾淨。我很高興能在以後再回過頭來看看。我有一個預感減少將是有用的,但我總是忽視它贊成地圖和過濾器。謝謝! – MattyRad

+0

不客氣;-) – trincot

0

你可以使用_.groupBy()LoDash庫:

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);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.2/lodash.js"></script>