Loop к структуре файловой системы в моем объекте, чтобы получить все файлы
Я получаю Javascript Object с моего сервера, который изображает файловую систему. Теперь я хочу получить путь от всех файлов в системе, например. конечные точки дерева.
Пример структуры файла:
└── pages
└── services
└── project
│── headline
│── test
│ └── text
│ └── picture
│── text
Считываемый JSON:
{
"path":"/pages/services/project",
"is_dir":true,
"children":[
{
"path":"/pages/services/project/headline",
"is_dir":false,
"children":[
]
},
{
"path":"/pages/services/project/text",
"is_dir":false,
"children":[
]
},
{
"path":"/pages/services/project/test/",
"is_dir":true,
"children":[
{
"path":"/pages/services/project/test/text",
"is_dir":false,
"children":[
]
},
{
"path":"/pages/services/project/test/picture",
"is_dir":false,
"children":[
]
}
]
}
] }
Ожидаемый результат:
/pages/services/project/headline
/pages/services/project/text
/pages/services/project/test/text
/pages/services/project/test/picture
Я немного поиграл с рекурсией и сделал тупую функцию, которая работает, когда в директории есть только один ребенок. Моя проблема в том, что я не могу понять, как обращаться с большим количеством детей. Есть ли способ перебора каждого ребенка?
Здесь мой код:
var json = {"path":"/pages/services/project", "is_dir":true, "children":[{"path":"/pages/services/project/headline","is_dir":false,"children":[]},{"path":"/pages/services/project/text","is_dir":false,"children":[]},
{"path":"/pages/services/project/test/","is_dir":true,"children":[{"path":"/pages/services/project/test/text","is_dir":false,"children":[]},
{"path":"/pages/services/project/test/picture","is_dir":false,"children":[]}]}]};
json.children.forEach(function (child) {
out(goToDeepestPoint(child).path);
});
function goToDeepestPoint(node) {
if (node.is_dir)
return goToDeepestPoint(node.children[0]);
else
return node;
}
function out()
{
var args = Array.prototype.slice.call(arguments, 0);
document.getElementById('output').innerHTML += args.join(" ") + "\n";
}
<pre id="output"></pre>
Ответы
Ответ 1
Я был занят игрой с вашим оригинальным вопросом и получил эту работу:
goToDeepestPoint(json);
function goToDeepestPoint(node) {
if (node.is_dir)
node.children.forEach(function (child) {
goToDeepestPoint(child);
});
else
return out(node.path);
}
Может быть не уместно в свете вашего редактирования, но стыдно тратить его!
Ответ 2
var json = {"path":"/pages/services/project", "is_dir":true, "children":[{"path":"/pages/services/project/headline","is_dir":false,"children":[]},{"path":"/pages/services/project/text","is_dir":false,"children":[]},
{"path":"/pages/services/project/test/","is_dir":true,"children":[{"path":"/pages/services/project/test/text","is_dir":false,"children":[]},
{"path":"/pages/services/project/test/picture","is_dir":false,"children":[]}]}]};
function getPaths(obj){
let foundPaths = [];
if(obj.children.length > 0){
obj.children.forEach(function (element){
let childPaths = getPaths(element);
foundPaths = foundPaths.concat(childPaths);
});
return foundPaths;
} else {
foundPaths.push(obj.path);
return foundPaths;
}
}
let paths = getPaths(json);
document.getElementById('output').innerHTML += paths.join("\n");
<pre id="output"></pre>
Ответ 3
Рабочее решение :
var json = {"path":"/pages/services/project", "is_dir":true, "children":[{"path":"/pages/services/project/headline","is_dir":false,"children":[]},{"path":"/pages/services/project/text","is_dir":false,"children":[]},
{"path":"/pages/services/project/test/","is_dir":true,"children":[{"path":"/pages/services/project/test/text","is_dir":false,"children":[]},
{"path":"/pages/services/project/test/picture","is_dir":false,"children":[]}]}]};
json.children.forEach(function (child) {
goToDeepestPoint(child);
});
function goToDeepestPoint(node) {
if (node.is_dir){
for(var i=0;i<node.children.length;i++){
goToDeepestPoint(node.children[i]);
}
}
else {
out(node.path);
}
}
function out()
{
var args = Array.prototype.slice.call(arguments, 0);
document.getElementById('output').innerHTML += args.join(" ") + "\n";
}
Ответ 4
Я поделюсь своим ответом, потому что он имеет отношение к тому, над чем я работал в данный момент, - он требует более функционального подхода, потому что это просто то, что я изучал.
Стойкие итераторы
Итераторы с явным комментарием JavaScript меня огорчают, поэтому мы можем реализовать постоянный интерфейс итератора, используя наши собственные типы Yield
и Return
. Используется тип Memo
, но это просто детали оптимизации.
const Memo = (f, memo) => () =>
memo === undefined
? (memo = f (), memo)
: memo
const Yield = (value, next = Return) =>
({ done: false, value, next: Memo (next) })
const Return = value =>
({ done: true, value })
// example use
const ArrayIterator = (xs = []) =>
xs.length === 0
? Return ()
: Yield (xs [0], () => ArrayIterator (xs.slice (1)))
const it =
ArrayIterator ([1,2,3])
console.log (it.value) // 1
console.log (it.value) // 1
console.log (it.next () .value) // 2
console.log (it.next () .value) // 2