0

Using javascript only, is there a way to locate a property within an array that is itself within another array and return its "path"?

Imagine a hierarchical group of nested arrays much like this example:

    var bigBox = [  

        mediumBoxA = [
                smallBoxA = [                  
                         toyA = { toyId : "Blue Ball"},
                         toyb = { toyId : "Pink Ball"}
                    ],

                smallBoxB = [                  
                         toyA = { toyId : "Girl Doll"},
                         toyB = { toyId : "Boy Doll"}
                    ],
            ],

        mediumBoxB = [
                smallBoxA = [                  
                         toyA = { toyId : "Batman"},
                         toyB = { toyId : "Superman"}
                    ],

                smallBoxB = [                  
                         toyA = { toyId : "Lego"},
                         toyB = { toyId : "Soldier"}
                    ],
            ]

   ];

Given that, in the console I want to be able to search for example: "Batman" and get that it is located in bigBox > mediumBoxB > smallBoxA > toyA. Again, I'm looking for a JS only solution and something I can implement on the console. No HTML involved.

Now, I know that i could go only by the index number, I used labels on each array such as "smallBox", "toyB", etc.. for explanation purposes.

Thank you guys!

1
  • 1
    Use a recursive function that iterate on the array then call himself if a sub-array is found. Pass the current "path" in paramater and if the value is found then print the whole path. Commented Apr 1, 2014 at 22:39

2 Answers 2

2

I've implemented a recursive function, which finds the path and returns it as an array:

/**
 * Finds an value and returns the path of nested variable names
 * 
 * @param {obj}       The object to search in
 * @param {search}    The value to search for
 * @param {variables} The relevant variables names or the context object
 * @param {context}   The context object in which to search the variable names
 *
 * @return The found path as an array or null if nothing was found
 */
function getPath(obj, search, variables, context) {

    if(context === undefined) {
        context = window;        
    }

    if(variables === undefined) {
        variables = window;
    }
    if(!Array.isArray(variables)) {
        // if variables is an object, this object is the context
        context = variables;
        // copy the keys to the variables array
        variables = [];
        for(var key in context) {
            if(context.hasOwnProperty(key)) {
                try {
                    // try to read property
                    context[key];
                    // push key to variable names
                    variables.push(key);
                } catch(e) {
                    // some properties of the window object cannot be read
                }
            }
        }
    }

    function getVariableName(variable) {
        for(var i = 0; i < variables.length; i++) {
            var name = variables[i];
            if(context[name] === variable) {
                // return variable name
                return name;
            }
        }
        return null;
    }

    function _getPath(variable, path) {
        if(typeof variable === 'object') {
            var name = getVariableName(variable);
            if(name) {
                var pathCopy = path.slice(0);
                pathCopy.push(name);
                for(var key in variable) {
                    // recursive call of _getPath
                    var returnedPath = _getPath(variable[key], pathCopy);
                    if(returnedPath) {
                        return returnedPath;
                    }
                }
            }            
        } else if(variable === search) {
            return path;
        }
        // if nothing was found, return null
        return null;
    }

    // now recursively search for the value
    return _getPath(obj, []);
}

With the function getPath you can do the following:

var path = getPath(bigBox, "Batman");
console.log(path.join(" > ")); // logs "bigBox > mediumBoxB > smallBoxC > toyE"

If all of your variables are in one object, you can also call the getPath function with an additional context argument like this:

var path = getPath(context.bigBox, "Batman", context);



I've changed the object bigBox a little bit, so that every variable is exactly once in the object.

Here is the jsFiddle demo

Sign up to request clarification or add additional context in comments.

Comments

0

Yes, you can walk through the tree using enumeration, and get the name of each key by simply using the for x in y syntax. In each iteration, the key's name is in the value of X. You can use your own preferred recursive or iterative implementation for scanning the tree and constructing a search path, then return the built path once you find your matching value.

That's the naive implementation in any case. There might be some faster ways to do tree searches; I'm not a computer scientist.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.