The Only One Around The Only One Around - 1 month ago 6
Javascript Question

build path to deep object in JavaScript

I have this code:

const getObject = (container, id, callback) => {
_.each(container, (item) => {
if (item.id === id) callback(item);
if (item.files) getObject(item.files, id, callback);
});
}


that will get me the object inside an object such as this:

const structure = {
id: 1,
name: "Struct",
files: [
{
id: 2,
type: "folder",
name: "assets",
files: [
{
id: 3,
type: "folder",
name: "important",
files: [
{
id: 4,
type: "folder",
name: "modules",
files: [
{
id: 5,
type: "folder",
name: "foo",
files: [
{
type: "file",
name: "foo.js"
}

]
},
{
id: 6,
type: "folder",
name: "bar",
files: [
{
type: "file",
name: "bar.js"
}

]
}
]
}

]
}
]
}
]
}


Example:

getObject(structure.files, 6, (target) => {
console.log(target)
}) // returns { "id": 6, "type": "folder", "name": "items", "files": [ { "type": "file", "name": "bar.json" } ] }


My problem is that I need to get the "path" back to the initial element (
structure.files
). What is the best way to go around this?

For example in this situation, it would return
[1,2,3,4,6]
.

Answer

You could use the classic function and this argument for the path in the callback for Array#some. Return full path when the target is found.

var structure = { id: 1, name: "Struct", files: [{ id: 2, type: "folder", name: "assets", files: [{ id: 3, type: "folder", name: "important", files: [{ id: 4, type: "folder", name: "modules", files: [{ id: 5, type: "folder", name: "foo", files: [{ type: "file", name: "foo.js" }] }, { id: 6, type: "folder", name: "bar", files: [{ type: "file", name: "bar.js" }] }] }] }] }] },
    path;

[structure].some(function iter(a) {
    if (a.id === 6) {
        path = this.concat(a.id);
        return true;
    }
    if (Array.isArray(a.files)) {
        a.files.forEach(iter, this.concat(a.id))
    }
}, []);

console.log(path);

Comments