使用字符串访问包含属性的数组[重复]

Posted

技术标签:

【中文标题】使用字符串访问包含属性的数组[重复]【英文标题】: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"]这样的字符串格式的表达式。它肯定会奏效。 【参考方案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 为我提供了一些关于解析字符串的好主意。旁注,我将不得不更多地研究正则表达式,因为我真的是一个菜鸟。

以上是关于使用字符串访问包含属性的数组[重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用字符串访问嵌套属性[重复]

使用点符号字符串访问对象子属性[重复]

js处理一个数组中包含多个对象,根据对象的一个属性查找到这个对象

无论如何使用包含数组名称的字符串来访问/修改数组?

检查字符串是不是包含数组的任何元素[重复]

如何查找数组是不是包含字符串[重复]