2014-03-03 88 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);