使用 JavaScript 查找给定值的完整对象路径

Ser*_*kiy 3 javascript

我有一个包含项目(只有name属性)和组(带有children属性,它们可能包含项目或其他组)的对象数组,我需要获得一个完整的needle值路径,所以在这种情况下它会是myObj[2]["children"][0]["children"][1]["children"][0],加上我仅限于相当旧的 JS 版本 ECMA 262(我在 Photoshop 中使用它)

var myObj = [
{
    "name": "group1",
    "children": [
    {
        "name": "group2",
        "children": [
        {
            "name": "item0"
        }]
    }]
},
{
    "name": "item1"
},
{
    "name": "needleGroup",
    "children": [
    {
        "name": "needleNestedGroup",
        "children": [
        {
            "name": "item3"
        },
        {
            "name": "needleNestedDeeperGroup",
            "children": [
            {
                "name": "needle"
            }]
        }]
    }]
}];
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是将对象转换为数组或数组,这样处理起来会更容易,所以我的对象变成了

[
    [
        [
            "item0"
        ]
    ],
    "item1", 
    [
        [
            "item3", 
            [
                "needle"
            ]
        ]
    ]
];
Run Code Online (Sandbox Code Playgroud)

但是……就是这样。我无法弄清楚只跟踪我需要的索引。你能指出一个正确的方向吗?

ibr*_*rir 6

使用递归函数查找您想要的项目。一旦函数找到它,它将返回一个数组。递归的每一步都会unshift得到这一步的对象键:

function find(obj, item) {
    for(var key in obj) {                                   // for each key in obj (obj is either an object or an array)
        if(obj[key] && typeof obj[key] === "object") {      // if the current property (value of obj[key]) is also an object/array
            var result = find(obj[key], item);              // try finding item in that object
            if(result) {                                    // if we find it
                result.unshift(key);                        // we shift the current key to the path array (result will be an array of keys)
                return result;                              // and we return it to our caller
            }
        } else if(obj[key] === item) {                      // otherwise (if obj[key] is not an object or array) we check if it is the item we're looking for
            return [key];                                   // if it is then we return the path array (this is where the path array get constructed)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此函数的输出将是指向 的键数组item。您可以轻松地将其转换为问题中的格式:

function findFormatted(obj, item) {
    var path = find(obj, item);                             // first let's get the path array to item (if it exists)
    if(path == null) {                                      // if it doesn't exist
        return "";                                          // return something to signal its inexistance
    }
    return 'myObj["' + path.join('"]["') + '"]';            // otherwise format the path array into a string and return it
}
Run Code Online (Sandbox Code Playgroud)

例子:

function find(obj, item) {
    for(var key in obj) {                                   // for each key in obj (obj is either an object or an array)
        if(obj[key] && typeof obj[key] === "object") {      // if the current property (value of obj[key]) is also an object/array
            var result = find(obj[key], item);              // try finding item in that object
            if(result) {                                    // if we find it
                result.unshift(key);                        // we shift the current key to the path array (result will be an array of keys)
                return result;                              // and we return it to our caller
            }
        } else if(obj[key] === item) {                      // otherwise (if obj[key] is not an object or array) we check if it is the item we're looking for
            return [key];                                   // if it is then we return the path array (this is where the path array get constructed)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:数组的索引也被格式化为字符串,但这不会成为问题,因为someArray["2"]相当于someArray[2].