【问题标题】:Javascript: How to Get Object property using Array of string? [duplicate]Javascript:如何使用字符串数组获取对象属性? [复制]
【发布时间】:2017-08-09 08:50:45
【问题描述】:

如何使用字符串数组(属性名称)获取对象属性? (数组的最后一个元素是对象的内部属性)

请看下面的代码:

方便的方法:

let myObject = {
    "property": {
        "subproperty": {
            "targetproperty": "Hi, We done it!"
        }
    }
};
let myString = "property:subproperty:targetproperty";
let parts = myString.split( ":" );
console.log( myObject[ parts[ 0 ] ][ parts[ 1 ] ][ parts[ 2 ] ] ); // Output: "Hi, We done it!"

评估方式:

let myObject = {
    "property": {
        "subproperty": {
            "targetproperty": "Hi, We done it!"
        }
    }
};
let myString = "property:subproperty:targetproperty";
let parts = myString.split( ":" );
let code = "myObject";
for ( let i = 0; i < parts.length; i++ ) {
    code += "['" + parts[ i ] + "']";
}
code += ";";
console.log( code );
console.log( eval( code ) ); // Output: "Hi, We done it!"

评估是邪恶的。所以我需要一种更清洁的方法来做到这一点。

如果没有 eval 和方便的工作,我该怎么做?

【问题讨论】:

    标签: javascript arrays string object


    【解决方案1】:

    你可以使用.reduce():

    let myObject = {
      "property": {
        "subproperty": {
          "targetproperty": "Hi, We done it!"
        }
      }
    };
    let myString = "property:subproperty:targetproperty";
    let value = myString.split(":").reduce(function(obj, prop) {
      return obj && obj[prop];
    }, myObject);
    
    console.log(value);

    【讨论】:

      【解决方案2】:

      for循环:

      function getByValue(arr, value) {
      
        for (var i=0, iLen=arr.length; i<iLen; i++) {
      
          if (arr[i].b == value) return arr[i];
        }
      }
      

      .过滤器

      function getByValue2(arr, value) {
      
        var result  = arr.filter(function(o){return o.b == value;} );
      
        return result? result[0] : null; // or undefined
      
      }
      

      .forEach

      function getByValue3(arr, value) {
      
        var result = [];
      
        arr.forEach(function(o){if (o.b == value) result.push(o);} );
      
        return result? result[0] : null; // or undefined
      
      }
      

      另一方面,如果您确实是指 for..in 并且想要查找具有任何值为 6 的属性的对象,那么您必须使用 for..in 除非您将名称传递给检查。例如

      function getByValue4(arr, value) {
        var o;
      
        for (var i=0, iLen=arr.length; i<iLen; i++) {
          o = arr[i];
      
          for (var p in o) {
            if (o.hasOwnProperty(p) && o[p] == value) {
              return o;
            }
          }
        }
      }
      

      【讨论】:

        【解决方案3】:

        递归方式;)

        创建一个获取当前属性、所有部分和索引的函数。

        从零开始,返回对下一个索引的调用,尝试读取并返回下一个调用并增加索引,直到没有更多的道具可供读取/提取,然后将您获得的值作为当前属性返回。

        如果您需要工作代码,请告诉我

        【讨论】:

          【解决方案4】:

          这是一种递归方法,如果找不到该属性,它将返回undefined

          const getPath = (o, keyPath, delimiter = '.') => {
              if (Array.isArray(keyPath)) {
                  keyPath = keyPath.join(delimiter)
              }
            // o might not be an object when called recursively
            if(Object(o) === o) {
              let keys = keyPath.split(delimiter);
              let key  = keys.shift();
          
              if(o.hasOwnProperty(key)) {
                if(keys.length) {
                  // there are more keys to check, call with attribute and remaining keys
                  return getPath(o[key], keys.join(delimiter), delimiter);
                } else {
                  // no more keys to check and object does have property
                  return o[key];
                }
              }
              // didn't early return from having the key above, object does not have property
              return undefined;
            } else if(keyPath.length === 0) { 
              // o is not an object, but there is no remaining keyPath, so we will assume we've unwound the stack
              return o;
            }
            // not an object and keyLength is non-zero, object does not contain property
            return undefined;
          };
          
          let myObject = {
              "property": {
                  "subproperty": {
                      "targetproperty": "Hi, We done it!"
                  }
              }
          };
          
          console.log(getPath(myObject, "property:subproperty:targetproperty", ":"));

          【讨论】:

            【解决方案5】:

            您可以遍历您的 parts 数组,在每次迭代中访问每个键的值。

            function valueFromPath(obj, path) {
              for (var i = 0; i < path.length; ++i) {
                obj = obj[path[i]];
              }
            
              return obj;
            };
            
            valueFromPath(myObject, parts);
            

            您可能想先克隆该对象,以防您将其用于其他用途。


            或者,您可以使用traverse。特别是traverse#getpath

            traverse(myObject).get(parts);
            

            【讨论】:

              【解决方案6】:

              您可以使用reduce 解决方案:

              var obj = {prop1: {prop2: {prop3: 'xpto'}}};
              var props = ['prop1','prop2','prop3'];
              
              var result = props.reduce((acc,val)=>acc[val],obj);
              console.log(result);
              

              【讨论】:

              • =&gt;acc[val] 应该是 =&gt;acc &amp;&amp; acc[val] 以检查 acc 不是 undefined
              【解决方案7】:

              你可以这样做;

              function getNestedValue(o,...a){
                var val = o;
                for (var prop of a) val = typeof val === "object" &&
                                                 val !== null     &&
                                                 val[prop] !== void 0 ? val[prop]
                                                                      : undefined;
                return val;
              }
              
              let myObject = {
                  "property": {
                      "subproperty": {
                          "targetproperty": "Hi, We done it!"
                      }
                  }
              };
              let myString = "property:subproperty:targetproperty";
              
              console.log(getNestedValue(myObject, ...myString.split(":")));

              【讨论】:

                猜你喜欢
                • 2020-04-16
                • 1970-01-01
                • 2015-08-13
                • 1970-01-01
                • 2018-06-08
                • 1970-01-01
                • 2012-07-05
                • 2017-07-16
                • 1970-01-01
                相关资源
                最近更新 更多