Javascript:如何使用字符串数组获取对象属性?

时间:2017-03-17 17:17:38

标签: javascript arrays string object

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

请参阅以下代码:

方便的方式:

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是邪恶的。所以我需要一种更清洁的方法来做到这一点。

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

7 个答案:

答案 0 :(得分:9)

您可以使用.reduce()

&#13;
&#13;
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);
&#13;
&#13;
&#13;

答案 1 :(得分:3)

For loop:

function getByValue(arr, value) {

  for (var i=0, iLen=arr.length; i<iLen; i++) {

    if (arr[i].b == value) return arr[i];
  }
}

.filter

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

}

另一方面,如果您确实想要...并且想要找到具有值为6的任何属性的对象,则必须使用for..in,除非您传递名称以进行检查。 e.g。

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;
      }
    }
  }
}

答案 2 :(得分:0)

递归方式;)

创建一个获取当前属性,allparts和index的函数。

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

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

答案 3 :(得分:0)

您可以遍历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);

答案 4 :(得分:0)

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

&#13;
&#13;
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", ":"));
&#13;
&#13;
&#13;

答案 5 :(得分:0)

您可以使用reduce解决方案:

var obj = {prop1: {prop2: {prop3: 'xpto'}}};
var props = ['prop1','prop2','prop3'];

var result = props.reduce((acc,val)=>acc[val],obj);
console.log(result);

答案 6 :(得分:0)

您可以执行以下操作;

&#13;
&#13;
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(":")));
&#13;
&#13;
&#13;