2

I have a object graph with the following structure:

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

It consists of objects and arrays of objects. I need to get every Element but the graph has an unknown number of levels. So, in order to go through all elements, a recursive loop is needed (I guess?).

Now I have two different tasks:

1.) First the easier one: I want to search for an attribute name (value of an object) and not return true (found) or false, but return the object, in which I found this value. (assume there is just one instance with the exact name).

2.) At the last level objects (e.g. 'obj element #1' with its attributes 'name', 'comment' and 'etc.') I want to call another method and pass as a parameter the complete path there: In this example one of the paths would be:

Topic -> obj #2 -> obj element #1. And the next one (for the next call of the function):

Topic -> obj #2 -> obj element #2.

So it will need an array to store the 'path' over the recursion. This array also needs to be altered, e.g. when going to the next element, it is necessary to delete the last element of the path and add the new element (#2). Same, when going coming back from recursion.

Here is what I tried (it is obviously not right and maybe some returns are useless/too much). Regarding 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;
}

I hope you guys understand what I mean. I'm grateful for every answer!

kerimrohs
  • 69
  • 1
  • 9
  • 3
    You **can't** (reasonably) search through the JSON. Instead, parse it, and then search through the resulting object graph. JSON is a *textual notation* for data exchange. [(More here.)](http://stackoverflow.com/a/2904181/157247) If you're dealing with JavaScript source code, and not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Sep 20 '17 at 17:05
  • See [this question's answers](https://stackoverflow.com/questions/44054176/recursively-searching-for-a-property-in-object) and try to apply them to your problem. If you get stuck on a specific point after doing more research, [searching SO thoroughly](/help/searching), etc., post a question with a valid example of the structure you need to search in JavaScript syntax, your attempt to solve the problem, and a clear explanation of where you're stuck. – T.J. Crowder Sep 20 '17 at 17:08
  • Sorry my mistake! I mean an array of nested objects. Didn't know the term JSON was wrong. I also added my code so far – kerimrohs Sep 20 '17 at 17:52
  • Added code **** – kerimrohs Sep 21 '17 at 16:13

1 Answers1

1

I solved the first part like this:

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;
}

That's what I needed. Maybe you find some unnecessary parts in it? I'm not the best with recursion.

Cost me the late evening, but now I also solved my second question. I will write my solution, in case other people have similar problems:

function getPaths(obj, level, singlePathArray, allPaths)

This did the trick for collecting all paths. obj is the object graph, level limits the number of levels looping through the graph, singlePathArray collects the information for one single path and allPaths stores all completed single paths.

Important here (and I missed it first) is to differentiate the object:

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);
                }
            }
        }

}
Mogsdad
  • 44,709
  • 21
  • 151
  • 275
kerimrohs
  • 69
  • 1
  • 9