Ad

JS Uniquely Identify Nested Objects Properties

- 1 answer

I have a nested object like:

var nested = {
        k: 1,
        j: {
          i: 1,
          k: 0
        },
        o: function(a, bc) {},
        p: {
          k: 0,
          p: {
            py: 0,
            kg: 8
          }
        }
      }

And I try to loop it and generate a unique identifier from every property from 0 to n where n is the total number of properties of the var nested object. Given the above var nested I expect something like:

var nested = {
            k: 1, -> (0)
            j: {  -> (1)
              i: 1, -> (2) 
              k: 0 -> (3)
            },
            o: function(a, bc) {}, -> (4)
            p: { -> (5)
              k: 0, -> (6)
              p: { -> (7)
                py: 0, -> (8)
                kg: 8 -> (9)
              }
            }
          }

If more simpler then I want to count how many properties does an (nested) object have and console.log every property and its index. I will update the question with a code prototype

Ad

Answer

Here's a way to iterate through nested objects/arrays. You can either use the generated path that is passed to the callback as the unique identifier or you can iterate a counter in the callback as you go or coin whatever type of identifier you want.

function iterateProperties(obj, fn, path) {
    var newPath, prop, i;
    path = path || "top";
    if (Array.isArray(obj)) {
        for (var i = 0; i < obj.length; i++) {
            newPath = path + "[" + i + "]";
            fn(newPath, obj[i]);
            if (typeof obj[i] === "object") {
                iterateProperties(obj[i], fn, newPath);
            }
        }
    } else {
        path += ".";
        for (prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                newPath = path + prop;
                fn(newPath, obj[prop]);
                if (typeof obj[prop] === "object") {
                    iterateProperties(obj[prop], fn, newPath);
                }
            }
        }
    }
}


var nested = {
        k: 1,
        j: {
          i: 1,
          k: 0
        },
        o: function(a, bc) {},
        p: {
          k: 0,
          p: {
            py: 0,
            kg: 8
          }
        }
      }
      
iterateProperties(nested, function(path, val) {
    log(path, " = ", val);
}, "nested");
<script src="http://files.the-friend-family.com/log.js"></script>

The one requirement of the object passed to this function is that it cannot have circular obj references.

Ad
source: stackoverflow.com
Ad