2014-03-03 31 views
3

我試圖找出最有效的方法來做到這一點。我有1個單一的對象,看起來像:使用2個數組的下劃線嵌套子註釋

var comments = [{ 
    id: 1, 
    deleted: 0, 
    comment: 'I am the parent commenter', 
    created: 'Sun Mar 01 2014 18: 16: 53 GMT - 0800(PST)', 
    parent_id: null, 
    username: 'edmund' 
}, { 
    id: 2, 
    deleted: 0, 
    comment: 'I am a reply', 
    created: 'Sun Mar 02 2014 18: 16: 59 GMT - 0800(PST)', 
    parent_id: 1, 
    username: 'sally' 
}, { 
    id: 3, 
    deleted: 0, 
    comment: 'I'm also a reply', 
    created: 'Sun Mar 03 2014 18: 16: 59 GMT - 0800(PST)', 
    parent_id: 1, 
    username: 'susan' 
}]; 

它包含的意見,如果評論有一個非空parent_id,那麼它是一個孩子。所以我分裂成這2個陣列,像這樣:

var parents = [], children = []; 

_(comments).filter(function(comment) { 
    comment.parent_id === null ? parents.push(comment) : children.push(comment); 
}); 

那麼什麼是追加所有兒童特定父評論的最佳方式?我想是這樣的:

children.forEach(function(child) { 
    parents[child['parent_id']]['children'] = _.where(children, { parent_id : child.parent_id }); 
}); 

有沒有一種方法,我可以將所有的這些

+0

可孩子也是父母? –

+0

@TedHopp孩子永遠不會是父母(我只能嵌套一層)。 –

+0

@bob_cobb你的目標是做樹評論列表,不是嗎? – Evgeniy

回答

3

您可以使用_.groupBy,這樣

console.log(_.groupBy(comments, "parent_id")); 

這讓

{ '1': 
    [ { id: 2, 
     deleted: 0, 
     comment: 'I am a reply', 
     created: 'Sun Mar 02 2014 18: 16: 59 GMT - 0800(PST)', 
     parent_id: 1, 
     username: 'sally' }, 
    { id: 3, 
     deleted: 0, 
     comment: 'I\'m also a reply', 
     created: 'Sun Mar 03 2014 18: 16: 59 GMT - 0800(PST)', 
     parent_id: 1, 
     username: 'susan' } ], 
    null: 
    [ { id: 1, 
     deleted: 0, 
     comment: 'I am the parent commenter', 
     created: 'Sun Mar 01 2014 18: 16: 53 GMT - 0800(PST)', 
     parent_id: null, 
     username: 'edmund' } ] } 

現在,如果關鍵是null他們都是父母和所有其他元素是parent_id小號

var _ = require("underscore"); 
var groupedData = _.groupBy(comments, "parent_id"); 
var parents = groupedData["null"], children = _.omit(groupedData, "null"); 
console.log("Children:", children); 
console.log("Parents:", parents); 

輸出

Children: { '1': 
    [ { id: 2, 
     deleted: 0, 
     comment: 'I am a reply', 
     created: 'Sun Mar 02 2014 18: 16: 59 GMT - 0800(PST)', 
     parent_id: 1, 
     username: 'sally' }, 
    { id: 3, 
     deleted: 0, 
     comment: 'I\'m also a reply', 
     created: 'Sun Mar 03 2014 18: 16: 59 GMT - 0800(PST)', 
     parent_id: 1, 
     username: 'susan' } ] } 

Parents: [ { id: 1, 
    deleted: 0, 
    comment: 'I am the parent commenter', 
    created: 'Sun Mar 01 2014 18: 16: 53 GMT - 0800(PST)', 
    parent_id: null, 
    username: 'edmund' } ] 

要獲得expected result,您可以使用此

var _ = require("underscore"); 
var groupedData = _.groupBy(comments, "parent_id"); 
console.log(_.map(groupedData["null"], function(currentItem) { 
    return _.defaults(currentItem, {"children": groupedData[currentItem.id]}); 
})); 

輸出

[ { id: 1, 
    deleted: 0, 
    comment: 'I am the parent commenter', 
    created: 'Sun Mar 01 2014 18: 16: 53 GMT - 0800(PST)', 
    parent_id: null, 
    username: 'edmund', 
    children: 
    [ { id: 2, 
     deleted: 0, 
     comment: 'I am a reply', 
     created: 'Sun Mar 02 2014 18: 16: 59 GMT - 0800(PST)', 
     parent_id: 1, 
     username: 'sally' }, 
     { id: 3, 
     deleted: 0, 
     comment: 'I\'m also a reply', 
     created: 'Sun Mar 03 2014 18: 16: 59 GMT - 0800(PST)', 
     parent_id: 1, 
     username: 'susan' } ] } ] 
+1

+1。這可以完成大部分工作,但是它落後於OP的要求。它需要第二步爲每個父註釋添加一個'children'屬性,並將其設置爲'groupBy'結果的相應'parent_id'屬性的數組。 –

+0

@TedHopp請現在檢查,我已經包括一種方法來分開'父母'和'孩子'。 – thefourtheye

+0

不錯!是否有一個好的下劃線方法來合併(嵌套)父母中的孩子? –

0

如果您需要建立一棵樹 - 合併像1> 1.1>嵌套子元素1.1.1您可以使用此遞歸:

var raw = [ 
    { title : 'element_1', id : 1 }, 
    { title : 'element_2' , id : 2 }, 
    { title : 'element_3' , id : 3 }, 
    { title : 'element_11', id : 11, parent_id : 1 }, 
    { title : 'element_12' , id : 12, parent_id : 1 }, 
    { title : 'element_21', id : 21, parent_id : 2 }, 
    { title : 'element_22' , id : 22, parent_id : 2 }, 
    { title : 'element_31', id : 31, parent_id : 3 }, 
    { title : 'element_32' , id : 32, parent_id : 3 }, 
    { title : 'element_331', id : 331, parent_id : 33 }, 
    { title : 'element_332' , id : 332, parent_id : 33 }, 
    { title : 'element_111', id : 111, parent_id : 11 }, 
    { title : 'element_113' , id : 113, parent_id : 11 } 
], 

roots = {}, 
childs = {}; 

function tree(item) { 
    for (c in childs[item.id]){ 
     var el = childs[item.id][c]; 

     item.nodes = item.nodes || []; 
     item.nodes.push(el); 

     childs[el.id] && tree(el); 
    } 
} 

for (item in raw){ 
    if(!raw[item].parent_id){ 
     roots[item] = raw[item]; 
    } else { 
     var p_id = raw[item].parent_id; 

     childs[p_id] = childs[p_id] || []; 
     childs[p_id].push(raw[item]) 
    } 
} 

for (i in roots){ 
    tree(roots[i]) 
} 

console.log(roots);