如何在嵌套数组中查找属性并返回其位置

时间:2014-04-01 22:36:54

标签: javascript arrays search

仅使用javascript,是否有办法在数组中找到一个属性,该数组本身位于另一个数组中并返回其"路径"?

想象一下嵌套数组的一个分层组,就像这个例子一样:

    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"}
                    ],
            ]

   ];

鉴于此,在控制台中我希望能够搜索例如:" Batman"并得到它 位于 bigBox> mediumBoxB> smallBoxA> TOYA 再一次,我正在寻找一个只有JS的解决方案以及我可以在控制台上实现的东西。没有涉及HTML。

现在,我知道我只能通过索引编号,我在每个数组上使用标签,例如" smallBox"," toyB"等等。用于解释目的。

谢谢你们!

2 个答案:

答案 0 :(得分:2)

我已经实现了一个递归函数,它找到路径并将其作为数组返回:

/**
 * 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, []);
}

使用功能getPath,您可以执行以下操作:

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

如果所有变量都在一个对象中,您还可以使用其他上下文参数调用getPath函数:

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



我已经稍微更改了对象bigBox,因此每个变量在对象中只有一次。

以下是 jsFiddle demo

答案 1 :(得分:0)

是的,您可以使用枚举遍历树,并通过简单地使用for x in y语法获取每个键的名称。在每次迭代中,键的名称都是X的值。您可以使用自己喜欢的递归或迭代实现来扫描树并构建搜索路径,然后在找到匹配值后返回构建的路径。

无论如何,这是天真的实施。可能有一些更快的方法来进行树搜索;我不是计算机科学家。