Skip to main content

Given a flat array of objects linked to one another, it will nest them recursively. Useful for nesting comments, such as the ones on reddit.com.

//
// Use recursion. Use `Array.prototype.filter()` to filter the items where the id
// matches the link, then `Array.prototype.map()` to map each one to a new object
// that has a `children` property which recursively nests the items based on which
// ones are children of the current item. Omit the second argument, `id`, to
// default to `null` which indicates the object is not linked to another one (i.e.
// it is a top level object). Omit the third argument, `link`, to use `'parent_id'`
// as the default property which links the object to another one by its id.
const nest = (items, id = null, link = "parent_id") =>
    items
        .filter(item => item[link] === id)
        .map(item => ({ ...item, children: nest(items, item.id) }));

//
// Compiled
var _extends = Object.assign || function(target) {
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i];
            for (var key in source) {
                if (Object.prototype.hasOwnProperty.call(source, key)) {
                    target[key] = source[key];
                }
            }
        }
        return target;
    };

var nest = function nest(items) {
    var id = arguments.length <= 1 || arguments[1] === undefined
            ? null
            : arguments[1];
    var link = arguments.length <= 2 || arguments[2] === undefined
            ? "parent_id"
            : arguments[2];

    return items
        .filter(function(item) {
            return item[link] === id;
        }).map(function(item) {
            return _extends({}, item, { children: nest(items, item.id) });
        });
};

// --------------------------------------------------
// Example Usage
// --------------------------------------------------

// One top level comment
const comments = [
    { id: 1, parent_id: null },
    { id: 2, parent_id: 1 },
    { id: 3, parent_id: 1 },
    { id: 4, parent_id: 2 },
    { id: 5, parent_id: 4 }
];

const nestedComments = nest(comments); // [{ id: 1, parent_id: null, children: [...] }]