【问题标题】:Access an array containing properties with a string [duplicate]使用字符串访问包含属性的数组[重复]
【发布时间】:2013-06-04 21:47:21
【问题描述】:

我在尝试使用字符串访问全局数组索引的属性时遇到了问题。我动态生成的字符串看起来像这样:

var foo = "arr[0].prp[0].prp[1]"

数组中的索引及其深度是动态的,我只是提供一个示例来说明它的外观。

现在的问题是当我尝试使用这个字符串来获取这样的属性时,它失败了:

foo.somethingfoo["something"]window[foo].somethingwindow[foo]["something"]

不过,我可以使用 eval() 来让它工作,但我真的想在不使用它的情况下离开。

有人有什么建议或想法吗?

【问题讨论】:

  • 我首先想到的是 eval。
  • 这就是 eval 实际上的用途。仍然想知道这个字符串究竟是如何生成的;把它变成一个访问器数组至少会允许理智的选择。
  • 你为什么把它放在一个字符串里?这是干什么用的?
  • 对于那些想知道的人来说,字符串是通过单击许多项目列表中的项目生成的。然后我获取项目的 id 并基于它构造一个字符串,以便访问包含列表中所有项目信息的数组。
  • 直接访问something,而不是像window["arr"][0]["prp"][0]["prp"][1]["something"]这样的字符串格式的表达式。它肯定会奏效。

标签: javascript


【解决方案1】:

另一种方法:

    var obj = {
        arr: [{
            prp: [{
                prp: ['a', 'b', 'c']
            }]
        }]
    };
    var foo = "arr[0].prp[0].prp[1]";

    var path = foo.replace(/\]/g, "").replace(/\[/g, ".").split('.').reverse();
    var res = obj;
    while (path.length && res){
        var el = path.pop();
        res = res[el];
    }

    console.log(res);

【讨论】:

    【解决方案2】:

    *Live Demo*

    var part = {
        "arr": [
            {
                "prp": [
                    {
                        "prp": [
                            "result"
                         ]
                    }
                ]
            }
        ]
    };
    var foo = "arr[0].prp[0].prp[0]";
    
    function getValue(obj, chain) {
        var keys = chain.split('\.'),
            iterable = [];
        for (var i = 0, len = keys.length; i < len; i++) {
            var parts = keys[i].split('[');
            parts[1] = parts[1].replace('\]', '');
            iterable.push(parts[0], parts[1]);
        }
        target = obj[iterable[0]];
    
        for (var j = 1, len = iterable.length; j < len; j++) {
            target = target[iterable[j]];
        };
        return target;
    };
    

    【讨论】:

    • 感谢您提供演示
    【解决方案3】:

    使用eval 可能不是一个好主意,因此我将提供一个替代解决方案。如果您提供了字符串的生成方式,则可以省去解析它并改写生成器的麻烦。

    你生成了一个看起来像这样的字符串

    var foo = "arr[0].prp[0].prp[1]";
    

    如果你使用像 /\[\d+\]|\..*?(?=[\.\[])/ig 这样的 RegExp 会发生什么?

    var m = foo.match(/\[\d+\]|\..*?(?=[\.\[])|^.*?(?=[\.\[])/ig);
    // ["arr", "[0]", ".prp", "[0]", ".prp", "[1]"]
    

    只需要多一点解析

    m = m.map(function (e) {
        if (e.charAt(0) === '.') return e.slice(1);
        else if (e.charAt(0) === '[') return e.slice(1, -1);
        else return e
    });
    // ["arr", "0", "prp", "0", "prp", "1"]
    

    现在你可以遍历它了

    var o = window, i;
    for (i = 0; i < m.length; ++i) {
        o = o[m[i]];
    }
    // o is now the result of window.arr[0].prp[0].prp[1]
    

    【讨论】:

    • 谢谢,您和@flav 为我提供了一些关于解析字符串的好主意。旁注,我将不得不更多地研究正则表达式,因为我真的是一个菜鸟。
    猜你喜欢
    • 2016-01-09
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    相关资源
    最近更新 更多