RKS_Code
RKS_Code

Reputation: 530

Find matching nodes in a tree with full path

I have an array of objects like this

[{
    name: "Peter",
    children: [{
        name: "John",
        children: [{
            name: "Joseph",
            children: []
        }]
    }, {
        name: "Shawn",
        children: [{
            name: "Joseph",
            children: []
        }]
    }]
}, {
    name: "Carl",
    children: [{
        name: "Sam",
        children: [{
            name: "JohnXX",
            children: []
        }]
    }]
}]

Where each person can have multiple children and each of these children can have any number of children and so on.

I want to retain the full path with matching children and exclude non matching children.For example if I search for John output should be like this

[{
    name: "Peter",
    children: [{
        name: "John",
        children: [{
            name: "Joseph",
            children: []
        }]
    }]
}, {
    name: "Carl",
    children: [{
        name: "Sam",
        children: [{
            name: "JohnXX",
            children: []
        }]
    }]
}]

Upvotes: 1

Views: 562

Answers (1)

Nina Scholz
Nina Scholz

Reputation: 386560

You need to generate a new object with only the relevant parts.

This proposal works iterative for a single level and recursive for the children.

function getNodes(array, cb) {
    return array.reduce(function iter(r, a) {
        var children;
        if (cb(a)) {
            return r.concat(a);
        }
        if (Array.isArray(a.children)) {
            children = a.children.reduce(iter, []);
        }
        if (children.length) {
            return r.concat({ name: a.name, children: children });
        }
        return r;
    }, []);
}

var data = [{ name: "Peter", children: [{ name: "John", children: [{ name: "Joseph", children: [] }] }, { name: "Shawn", children: [{ name: "Joseph", children: [] }] }] }, { name: "Carl", children: [{ name: "Sam", children: [{ name: "JohnXX", children: [] }] }] }];

console.log(getNodes(data, function (o) { return o.name.indexOf('John') !== -1; }));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Related Questions