【问题标题】:Dynamically Invoke an object a few levels down in Javascript?在Javascript中动态调用一个对象几级?
【发布时间】:2014-01-18 01:19:41
【问题描述】:
var myObj = {
    bar_foo : "test",
    bar : {
       foo : "hi there";
         },
    foo : {
          bar : {
                 foo: "and here we go!"
                 }
           }
     }

如何获得:

var arr = [["bar", "foo"], ["foo", "bar", "foo"]];

返回这个:

myObj["bar"]["foo"];
myObj["foo"]["bar"]["foo"];

arr 可以是任意长度,以便遍历对象。

所以我们知道我们可以像这样动态调用对象的值:

var 通常 = myObj["bar_foo"];

normally 等于 "test"

但这种技术假设我们知道遍历的深度。

我要做的是通过提供数组来检索对象值

["bar", "foo"]

本质上与以下内容相同:

myObj["bar"]["foo"];

我这样做的原因是因为我正在根据我想要的 arr 值创建一个新对象。

所以最终结果是:

arr_new = myObj.someMethod(arr);

arr_new 在哪里:

arr_new : ["hi there", "and here we go!"];

我希望能澄清一下。

【问题讨论】:

  • 你试过了吗?
  • 根本不是一个设置 - 我实际上是一个好人。当你展示你到目前为止所做的事情而不是“我该怎么做?”时,它只会有助于得到回应。值得发布您到目前为止所拥有的内容,我相信人们会帮助改进。
  • 您能否澄清一下您期望的结果是什么?由于您要列出语句,您是否想稍后生成代码字符串到eval()?还是那些意味着收集通过迭代每个键列表找到的值?
  • ...如果您不向我们展示您的尝试,我们怎么知道我们是否比您更聪明?
  • 输出的语法无效,不确定是数组还是对象数组

标签: javascript object dynamic return


【解决方案1】:

如果你正在使用 Underscore(或者可以使用原生 JS mapreduce),试试这个:

var myObj = {
  bar: {
    foo: "hi there"
  },
  foo: {
    bar: {
      foo: "and here we go!"
    }
  }
};

var arr = [
  ["bar", "foo"],
  ["foo", "bar", "foo"]
];

function deepProp(arr, obj) {
  return _.reduce(arr, function(memo, val) {
    return memo[val];
  }, obj);
}

var deepProps = _.map(arr, function(deepArray) {
  return deepProp(deepArray, myObj);
});

console.log(deepProps); // => ["hi there", "and here we go!"]

可能有更优雅的解决方案;这是一个快速破解。似乎几乎可以做你想做的事! :P

【讨论】:

  • 对于reduce,你可能需要return memo && (val in memo) ? memo[val] : null;来处理key不存在的情况。
  • @cookiemonster 是的,这就是为什么这只是一个快速破解。它假设嵌套数组对对象结构的了解是 100% 准确的。正如您所展示的那样,修复起来非常简单。
【解决方案2】:

也许这就是你要找的?

function getObjValue( arr, obj){
    var tmp=obj;
    for(i=0;i<arr.length;i++){
        tmp=tmp[arr[i]];
    }
    return tmp
}

alert( getObjValue( arr[1],myObj)); // "and here we go!"

创建值数组:

var result=arr.map(function(subArr){
   return  getObjValue(subArr,myObj);
})

DEMO

【讨论】:

    【解决方案3】:

    我做了一个小提琴显示一个可能的答案,没有使用库:

    http://jsfiddle.net/EfrainReyes/6s9HY/2/

    var traverseObject = function(obj, arr) {
        var results = [];
    
        for (var i = 0; i < arr.length; i++) {
            var tempObj = obj;
    
            for (var j = 0; j < arr[i].length; j++) {
                tempObj = tempObj[arr[i][j]];
            }
    
            results.push(tempObj);
        }
        return results;
    };
    

    当然,这假设参数将始终有效,但可以添加验证检查。

    【讨论】:

      【解决方案4】:
      Object.prototype.someMethod = function (arr) {
      
        function a (obj, array){
          var res = obj[array.splice(0, 1)[0]];
          if (typeof res === 'object' && array.length) {
            return a(res, array);
          }else{
            return res;
          }
        }
        var result = [];
        for (var i = 0; i < arr.length; i++) {
          result.push(a(this, arr[i]));
        }
        return result;
      };
      

      JSBin >> Demo

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-30
        • 2012-02-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多