问题描述:

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].

网友答案:

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;
    }
    return Array.isArray(a.files) && a.files.some(iter, this.concat(a.id));
}, []);

console.log(path);
网友答案:

More generic way of doing this. You don't need to check for specific id like the other answer! This will work even if you add more complex structure. Take a look.

I'm doing a recursive check and adding the id to the array which will be returned after going through all the possible paths. Hope it helps!

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

  function getId(obj, idArray) {
    var idArr = idArray ? idArray : []
    if (obj.files) {
      obj.id && idArr.push(obj.id)
      obj.files.forEach(function(nextObj, i) {
        if (nextObj.id)
         getId(nextObj, idArr)
       })
      return idArr
    }
  }
  console.log(getId(structure))
网友答案:
const recurse = function (container, id) {
  console.log("Now on node:", container);
  if (container.id === id) {
    console.log("Found the child whose existence was foretold!", container);
    var path = [];
    path.unshift(container.id);
    return path;
  } else {
    console.log("Your princess is in another castle", container);
    if (container.files && container.files.length > -1) {
      for(let i = 0; i < container.files.length; i++) {
        var child = container.files[i];
        var possiblePath = recurse(child, id);
        if (possiblePath) {
          possiblePath.unshift(container.id);
          console.log("This is " + container.id + " reporting in, we have the child.", possiblePath);
          return possiblePath;
        }
      }
    } else {
      return null;
    }
  }
}

const getObject = function(container, id, callback) {
  console.log("Starting recursion, looking for id", id);
  var path = recurse(container, id);
  if (path && path.length > 0) {
    console.log("Path to target element found", path);
  } else {
    console.log("Target element not found.");
  }
  callback(path);
}
相关阅读:
Top