5

Hey everyone I am trying t find the most dynamic way to loop through an array and return specific values return specific values... The json is deeply structured and may change, could there be a $.each() formula that can help?

Example:

var myobj = {
    obj1: { key1: 'val1', key2: 'val2' },
    obj2: { key1: '2val1', 
           key2: { nest1: 'val1', nest2: 'val2', nest3: 'val3' }, 
           key3: { nest1: 'K3val1', nest2: 'K3val2', 
                 nest3: [
                         { nest1: 'val1', nest2: 'val2', nest3: 'val3' }, 
                         { nest1: 'val1', nest2: 'val2', nest3: 'val3' }
                        ]
                 }
          },
    obj3: { key1: 'dddddval1', key2: 'val2' }
    }

now lets say i want to retrieve "K3val2" value but instead of hardcoding it like so: myobj.obj2.key3.nest2 is there a dynamic way I do this with $.each() mybe?

a better oliver
  • 26,330
  • 2
  • 58
  • 66
Simo Mafuxwana
  • 3,702
  • 6
  • 41
  • 59
  • 5
    Keyword: "recursion". Now it's time to google – zerkms Jul 09 '13 at 11:12
  • That's not an array, it's an object with a bunch of nested objects. (It *contains* one array, the one assigned to `nest3`.) (It's also not JSON, as tagged.) – T.J. Crowder Jul 09 '13 at 11:13
  • 2
    _"deeply structured and may change,"_ - So how do you know which key to even look for? The only example you gave is asking how to find a specific _value_ not the value associated with a specific _key_ so...? – nnnnnn Jul 09 '13 at 11:24
  • How do you want to "retrieve" the value if you don't know where it is located, how do you recognize that you found it? If you wanted to search for it you would know the value already… – Bergi Jul 09 '13 at 11:45
  • @nnnnnn that will depend on the specific value I have to pull out at that specific time, which means I will hook that in a trigger.. – Simo Mafuxwana Jul 09 '13 at 12:11

1 Answers1

19

You can simply nest calls to $.each:

Live Example | Live Source

// Loop the top level
$.each(myobj, walker);

function walker(key, value) {
    // ...do what you like with `key` and `value`

    if (value !== null && typeof value === "object") {
        // Recurse into children
        $.each(value, walker);
    }
}

If you want to know how deep you are, you can do that too:

Live Example | Live Source

var path = "";

// Loop the top level
$.each(myobj, walker);

function walker(key, value) {
    var savepath = path;

    path = path ? (path + "." + key) : key;

    // ...do what you like with `key` and `value`

    if (value !== null && typeof value === "object") {
        // Recurse into children
        $.each(value, walker);
    }

    path = savepath;
}
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • @T.J.Crowder your answer sparked a ideas thanks.. I came across an issue, if i have something like `{"Name": "Skipper The Penguin"}` on the first level. it will give each letter: s k i p p e r and so.. wrapping it all as an object solved it. Thank you – Simo Mafuxwana Jul 09 '13 at 12:03
  • @D'loDeProjuicer: Glad that helped. On the `{"Name": "Skipper The Penguin"}` thing, the code above **won't** do that, because it tests the value before recursing. That's what the `if (typeof value === "object")` is for. See it in action here: http://jsbin.com/ofifor/3 ([source](http://jsbin.com/ofifor/3/edit)). Also note I'd missed out a `null` check above, which I've added, you'll probably want that. – T.J. Crowder Jul 09 '13 at 12:39