2017-03-17 90 views
4

我如何使用字符串数组获取对象属性(属性的名称)? (在阵列的最后一个元素是物体的内属性)Javascript:如何使用字符串数组获取对象属性?

见下面的代码:

方便的方法:

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和方便的工作吗?

回答

9

您可以使用.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);

+0

这个答案是去天堂! –

+0

谢谢。这太棒了。 –

3

For循环:

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 

} 

如果,另一方面,你真的没有意思的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; 
     } 
    } 
    } 
} 
0

递归方式)

创建一个函数,它的电流特性,allparts和索引。

开始零,回叫下一个索引,尝试读取并与下一个电话和增量指标返回,直到有没有更多的道具读/提取物,然后返回你得到的当前属性的值。

让我知道如果你需要通过你的parts阵列工作代码

0

你可以循环,访问在每次迭代中每个键的值。

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); 
0

这里是一个递归方法,它将返回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", ":"));

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); 
+0

'=> acc [val]'应该是'=> acc && acc [val]'来检查'acc'不是'undefined'! –

0

你可以这样做:

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

相关问题