У меня есть граф объектов со следующей структурой:
topic
- obj #1
- obj #2
--- attr #2 name
--- attr #2 elements
------obj element #1
---------attr element #1 name
---------attr element #1 comment
---------attr element #1 etc.
------obj element #2
--- attr #2 etc.
- obj #3
Он состоит из объектов и массивов объектов. Мне нужно получить каждый элемент, но график имеет неизвестное количество уровней. Итак, чтобы пройти через все элементы, необходим рекурсивный цикл (я думаю?).
Теперь у меня есть две разные задачи:
1.) Сначала проще: я хочу искать имя атрибута (значение объекта) и не возвращать true (found) или false, а возвращать объект, в котором я нашел это значение. (предположим, что есть только один экземпляр с точным именем).
2.) На объектах последнего уровня (например, "obj element # 1" с его атрибутами "имя", "комментарий" и т.д.). Я хочу вызвать другой метод и передать в качестве параметра полный путь туда: в этом Например, один из путей:
Тема → объект # 2 → объект # 1. И следующий (для следующего вызова функции):
Тема → obj # 2 → объект obj # 2.
Поэтому ему понадобится массив для хранения "пути" по рекурсии. Этот массив также необходимо изменить, например, при переходе к следующему элементу необходимо удалить последний элемент пути и добавить новый элемент (# 2). То же самое, когда вы возвращаетесь из рекурсии.
Вот что я пробовал (это, очевидно, не так, и, может быть, некоторые из них бесполезны/слишком много). Относительно 1):
function findIdentifier (obj, identifier){
var el=null;
if(typeof obj === 'object'){
if (!Array.isArray(obj)){
for(var key in obj){
if (obj.hasOwnProperty(key)) {
if (key.indexOf(identifier) !== -1 || obj[key] === identifier){
//found right object
el = obj[key];
return el;
}
else el = findIdentifier(obj[Object.keys(obj)[0]],identifier);
}
}
return el;
}
else{
for(var i=0; i<obj.length; i++){
if (obj[i].indexOf(identifier) !== -1 && obj.length>1){
el = obj[i];
return el;
}
else el = findIdentifier(obj[0],identifier);
}
return el;
}
}
return el;
}
Надеюсь, вы понимаете, что я имею в виду. Я благодарен за каждый ответ!
Я решил первую часть следующим образом:
function findIdent (obj, identifierKey){
var res=null;
for (var i in obj) {
if (!!obj[i] && typeof(obj[i])==="object") {
console.log(i+" "+identifierKey);
if(i.indexOf(identifierKey) !== -1 || i === identifierKey){
return obj[i];
}
else res=findIdent(obj[i], identifierKey);
}
}
return res;
}
Это то, что мне нужно. Может быть, вы найдете в нем какие-то ненужные детали? Я не лучший с рекурсией.
Позаботьтесь о позднем вечером, но теперь я также решил свой второй вопрос. Я напишу свое решение, если у других людей возникнут аналогичные проблемы:
function getPaths(obj, level, singlePathArray, allPaths)
Это помогло собрать все пути. obj - это граф объектов, уровень ограничивает количество циклов, проходящих через график, singlePathArray собирает информацию для одного единственного пути, а всеPaths хранит все завершенные одиночные пути.
Важно здесь (и я пропустил это в первую очередь) - это дифференцировать объект:
if (!!obj && typeof(obj)==="object") {
if(!Array.isArray(obj)){
//push a object with path info in singlePathArray
//if desired level reached -> push singlePathArray into allPaths
//else call recursive function (obj: obj.elementsArray)
}else{
for (var i in obj) {
if (!!obj[i] && typeof(obj[i]) === "object") {
allPaths=getPaths(obj[i], level, singlePathArray,allPaths);
singlePathArray.splice(-1,1);
}
}
}
}