2017-03-17 98 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(":")));

相關問題