Javascript:通过将路径作为字符串传递给对象来从对象中获取深层价值[重复]

Posted

技术标签:

【中文标题】Javascript:通过将路径作为字符串传递给对象来从对象中获取深层价值[重复]【英文标题】:Javascript: Get deep value from object by passing path to it as string [duplicate] 【发布时间】:2012-02-07 16:45:17 【问题描述】:

可能重复:Accessing nested javascript objects with string key

可能是标题不够清楚,我只是不知道如何指定我要查找的内容,而且我的英语真的很糟糕,抱歉。

我正在尝试创建返回对象值的函数,但也可以很好地处理嵌套对象。例如:

var obj = 
  foo:  bar: 'baz' 
;

我想通过向函数提供字符串“foo.bar”来访问 obj.foo.bar 的值。

function(obj, path) 
  // Path can be "foo.bar", or just "foo".

谢谢!

【问题讨论】:

lodash 现在使用 _.get(obj, property) 支持此功能。见lodash.com/docs#get 由于这个问题被标记为重复(即使不是),我必须在评论中回答。您可以使用 ECMAScript6 解构:var obj = foo: bar: 'baz' ;(foo:bar:value = obj);console.log(value); 如果您想在检索值时正确处理任何问题,以及智能处理函数,请查看path-value 以帮助解决。 【参考方案1】:

这可以正常工作:

var deep_value = function(obj, path)
    for (var i=0, path=path.split('.'), len=path.length; i<len; i++)
        obj = obj[path[i]];
    ;
    return obj;
;

这是证明/演示:jsfiddle.net/tadeck/5Pt2q/13/

编辑:我删除了多余的变量,缩短了代码。

【讨论】:

漂亮。比重复中的任何东西都好***.com/questions/6491463/… @SteveBlack 怎么样?它支持更受限制的语法,并且在尝试解析不存在的密钥时不会进行错误检查。 我认为检查obj[path[i]] === undefined会更安全 改变参数是不好的做法。 ES6 相同:const deep_value = (o, p) =&gt; p.split('.').reduce((a, v) =&gt; a[v], o);【参考方案2】:

考虑一下:

var obj = 
  foo:  bar: 'baz' 
;

function deepFind(obj, path) 
  var paths = path.split('.')
    , current = obj
    , i;

  for (i = 0; i < paths.length; ++i) 
    if (current[paths[i]] == undefined) 
      return undefined;
     else 
      current = current[paths[i]];
    
  
  return current;


console.log(deepFind(obj, 'foo.bar'))

【讨论】:

@7elephant 和 qiao:如果路径的任何部分计算 null,则失败(抛出错误)。根据您的观点,这可能是一个功能或错误。 :-) 如何处理对象内部的数组?【参考方案3】:

你的意思是这样的?这是一个递归版本

function recLookup(obj, path) 
    parts = path.split(".");
    if (parts.length==1)
        return obj[parts[0]];
    
    return recLookup(obj[parts[0]], parts.slice(1).join("."));

见http://jsfiddle.net/kExSr/

【讨论】:

黄金!我能够使用它来将路径 /Root[1]/This/worked 映射到对象 "Root[1]":Thisworked:"value" 。不得不修剪前导 / 并改变 .到/但在其他方面很漂亮。 这看起来不太快。不应该再次加入()路径,只需检查路径是字符串还是数组【参考方案4】:

类似:

function(obj, path) 
  var current=obj; 
  path.split('.').forEach(function(p) current = current[p]; ); 
  return current;

【讨论】:

meta.stackexchange.com/a/118023/134069 另一种没有突变的方法:const lens = (obj, path) =&gt; path.split(".").reduce((o, key) =&gt; o &amp;&amp; o[key] ? o[key] : null, obj);【参考方案5】:

您希望在点上拆分字符串,然后重复索引到对象中,例如大致如下:

function goDeep(obj, path) 
    var parts = path.split('.'),
        rv,
        index;
    for (rv = obj, index = 0; rv && index < parts.length; ++index) 
        rv = rv[parts[index]];
    
    return rv;

Live example

之所以有效,是因为您可以通过几种不同的方式访问对象的属性:使用文字的点语法 (obj.foo),以及使用字符串的括号语法 (obj["foo"])。在后一种情况下,字符串可以是任何表达式的结果,它不必是字符串文字。在所有的中,rv 被设置为相同的值:

rv = obj.foo.bar;
// Or
rv = obj.foo["bar"];
// Or
f = "foo";
rv = obj[f].bar;
// Or
s = "b";
rv = obj.foo[s + "ar"];

【讨论】:

当然,这个需求没有被表达出来,但我们可能不会怀疑 OP 可能同样想要一个函数调用,比如goDeep(myObj, 'bar[3].baz')?这可能超出了当前问题的范围...... @DavidHedlund:公平点,检查每个 part 中的括号形式可能很有用,以便与 JavaScript 自己的语法完全兼容。我会把它作为 OP 的练习。 :-) (好吧,不是完全,因为要做到这一点,你必须基本上重新发明[或-颤抖-使用]eval。但是说,大部分兼容与。) 很好,在这种情况下,大部分兼容可能比完全兼容更可取:)

以上是关于Javascript:通过将路径作为字符串传递给对象来从对象中获取深层价值[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何将内存流作为字符串传递给 javascript

mod_rewrite:将路径和查询字符串 URL 作为参数传递

将字符串从控制器传递到部分视图作为 javascript 函数参数

如何将 mysql 数字类型数据从 php 传递到 Javascript 以作为字符串类型到达? [关闭]

将文件路径字符串传递给 Boost.Spirit 中的语义操作

在 Django 中将文件路径作为 URL 参数传递