0

Let's assume I have an array as following:

[
    {
        "name": "list",
        "text": "SomeText1"
    },
    {
        "name": "complex",
        "text": "SomeText2",
        "config": {
            "name": "configItem",
            "text": "SomeText3",
            "anotherObject": {
                "name": "anotherObject1",
                "text": "SomeText4"
            }
        }
    }
]

I am using this awesome code to get all Objects with a certain key (http://techslides.com/how-to-parse-and-search-json-in-javascript). In my example it is getObjects(data,'text','') which will return all nodes as Object due to the appearance of text as key.

My only problem is, that I need to know the location of the returned Object in the whole array.

Is there any way to get it? Or at least the depth of the object in conjunction to the array?

getObjects(r,'text','')[0] (name = list) -> depth 1

getObjects(r,'text','')[1] (name = complex) -> depth 1

getObjects(r,'text','')[2] (name = configItem) -> depth 2

JJJ
  • 32,902
  • 20
  • 89
  • 102
user1021605
  • 241
  • 3
  • 14
  • possible duplicate of [How to check the depth of an object?](http://stackoverflow.com/questions/13523951/how-to-check-the-depth-of-an-object) – Alex Jan 30 '15 at 12:18
  • Well, I don't need the deepest level of an object - I need the exact depth of an given object in my array. So nop, this link won't help me. – user1021605 Jan 30 '15 at 12:21
  • possible duplicate of [Getting indexOf Javascript array made up of Javascript Objects](http://stackoverflow.com/questions/7908810/getting-indexof-javascript-array-made-up-of-javascript-objects) – Michelangelo Jan 30 '15 at 12:50

2 Answers2

2

You will need something along these lines:

function getObjectsDepth(obj, key, val, depth) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjectsDepth(obj[i], key, val,++depth));    
        } else 
        //if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not)
        if (i == key && obj[i] == val || i == key && val == '') { //
            objects.push(depth);
        } else if (obj[i] == val && key == ''){
            //only add if the object is not already in the array
            if (objects.lastIndexOf(obj) == -1){
                objects.push(depth);
            }
        }
    }
    return objects;
}

This will return the depth of the object, but not the object itself, just pass a 0 or 1 as last param, based on how you want to count. If you want both the object and the depth at the same time you need to obj.push({'obj':obj,'depth':depth}).

Szabolcs Páll
  • 1,402
  • 6
  • 25
  • 31
  • Thank you ! I got another Problem. If I call getObjects(r,'config','') my return value ist null, although there is an object in my array. – user1021605 Jan 30 '15 at 13:15
  • It's because 'config' is an object so it's just get skipped. You should add `objects.push(obj);` after `if (typeof obj[i] == 'object') {` to get even that. – Szabolcs Páll Jan 30 '15 at 13:32
  • This will give me a lot of returnvalues which I don't want when quering for Key = text I'll think I need to debug this - thanks in Advance. – user1021605 Jan 30 '15 at 13:42
  • Actually there's a more elegant solution to the problem, simply delete the word `else` – Szabolcs Páll Jan 30 '15 at 13:44
1

Change the getObjects function by this one:

function getObjects(obj, key, val, depth) {
    var objects = [];
    depth = typeof depth !== 'undefined' ? depth : 0;
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            depth ++;
            objects = objects.concat(getObjects(obj[i], key, val, depth));    
        } else 
        //if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not)
        if (i == key && obj[i] == val || i == key && val == '') { //
            objects.push({"obj":obj,"depth": depth});
        } else if (obj[i] == val && key == ''){
            //only add if the object is not already in the array
            if (objects.lastIndexOf(obj) == -1){
                objects.push({"obj":obj,"depth": depth});
            }
        }
    }
    return objects;
} 

Now you get depth and the object.

Paulo Segundo
  • 448
  • 3
  • 6