Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nesting child comments using underscore with 2 arrays

I'm trying to figure out the most efficient way to do this. I have 1 single object that looks like:

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'
}];

It contains comments, and if a comment has a non-null parent_id, then it's a child. So I'm splitting these into 2 arrays like so:

var parents = [], children = [];

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

Now what is the best way to append all children for a particular parent comment? I was thinking something like this:

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

Is there a way I can combine all of these

like image 590
bob_cobb Avatar asked Feb 28 '26 12:02

bob_cobb


1 Answers

You can use _.groupBy, like this

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

That gives

{ '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' } ] }

Now, if the key is null they all are parents and all the other elements are the parent_ids

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);

Output

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' } ]

To get the expected result, you can use this

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

Output

[ { 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' } ] } ]
like image 72
thefourtheye Avatar answered Mar 03 '26 00:03

thefourtheye



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!