我有这段代码:
const getObject = (container, id, callback) => {
_.each(container, (item) => {
if (item.id === id) callback(item);
if (item.files) getObject(item.files, id, callback);
});
}
这将使我获得对象内的对象,例如:
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"
}
]
}
]
}
]
}
]
}
]
}
示例:
getObject(structure.files, 6, (target) => {
console.log(target)
}) // returns { "id": 6, "type": "folder", "name": "items", "files": [ { "type": "file", "name": "bar.json" } ] }
我的问题是我需要获得"路径"回到初始元素(structure.files
)。解决这个问题的最佳方法是什么?
例如,在这种情况下,它会返回[1,2,3,4,6]
。
答案 0 :(得分:1)
您可以在Array#some
的回调中使用经典函数和此参数作为路径。找到目标时返回完整路径。
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);

带有闭包的ES6版本,用于路径收集变量p
。
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,
iter = p => a => {
if (a.id === 6) {
path = p.concat(a.id);
return true;
}
return Array.isArray(a.files) && a.files.some(iter(p.concat(a.id)))
};
[structure].some(iter([]));
console.log(path);

答案 1 :(得分:0)
更通用的方法。您不需要像其他答案一样检查特定的id
!即使您添加更复杂的structure
,这也会有效。看一看。
我正在进行递归检查并将id
添加到数组中,该数组将在遍历所有可能的路径后返回。希望能帮助到你!
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))
答案 2 :(得分:0)
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);
}