[英]Pluck specific javascript value from an object based on an array of indexes
給定這樣的嵌套對象:
var cars = {
"bentley": {
"suppliers": [
{
"location": "England",
"name": "Sheffield Mines"}
]
// ...
}
};
像這樣的數組["bentley", "suppliers", "0", "name"]
,是否存在一個將pluck_innards(cars, ['bentley', "suppliers", "0", "name"])
最深元素的現有函數,即pluck_innards(cars, ['bentley', "suppliers", "0", "name"])
並返回“ Sheffield Mines”。
換句話說,有一個函數(我將其命名為deep_pluck
),其中
deep_pluck(cars, ['bentley', 'suppliers', '0', 'name'])
=== cars['bentley']['suppliers']['0']['name']
在我看來,這很簡單,但已足夠普遍,以至於可以在諸如jQuery或lo-dash / underscore之類的Javascript實用程序庫中完成-但我沒有看到它。
我的想法很瑣碎,大致如下:
function deep_pluck(array, identities) {
var this_id = identities.shift();
if (identities.length > 0) {
return deep_pluck(array[this_id], identities);
}
return array[this_id];
}
我已經在jsFiddle上發布了 。
如果函數足夠智能以識別何時需要數組中的數字索引,那當然會有所幫助。 我不確定還有什么需要注意的地方。
對於我認為已經巧妙解決的問題,這是一個相當長的問題,但是我想將其發布,因為我很想看看那里有什么解決方案。
我不認為如果將數字作為0
傳遞給數組索引,就不會有問題。
這是沒有遞歸的函數的替代版本:
function deep_pluck(object, identities) {
var result = object;
for(var i = 0; i < identities.length; i++) {
result = result[identities[i]];
}
return result;
}
此處的工作示例: http : //jsfiddle.net/AmH2w/1/
盡管不是通用庫,但CasperJS的utils.getPropertyPath
函數似乎具有這種類型的東西。
/**
* Retrieves the value of an Object foreign property using a dot-separated
* path string.
*
* Beware, this function doesn't handle object key names containing a dot.
*
* @param Object obj The source object
* @param String path Dot separated path, eg. "x.y.z"
*/
function getPropertyPath(obj, path) {
if (!isObject(obj) || !isString(path)) {
return undefined;
}
var value = obj;
path.split('.').forEach(function(property) {
if (typeof value === "object" && property in value) {
value = value[property];
} else {
value = undefined;
}
});
return value;
}
從那以后,我遇到了幾種解決方案,包括:
我還要注意相對較新的lodash.deep
。
dotty.get(obj,pathspec)執行此操作,接受數組或點分字符串作為pathspec。
Dotty是開源的,還具有一個exist方法和一個推桿。
該方法是遞歸的,並且與您的想法非常相似,不同之處在於dotty包含對null / undefined對象的測試,這樣它就不會為嘗試訪問不存在的元素而引發異常。
來自文檔的dotty.get()源發布在下面:
var get = module.exports.get = function get(object, path) {
if (typeof path === "string") {
path = path.split(".");
}
if (!(path instanceof Array) || path.length === 0) {
return;
}
path = path.slice();
var key = path.shift();
if (typeof object !== "object" || object === null) {
return;
}
if (path.length === 0) {
return object[key];
}
if (path.length) {
return get(object[key], path);
}
};
這是一個使用reduce
的簡短ES6實現:
function get(obj, keyPath) {
return keyPath
.split(".")
.reduce((prev, curr) => prev[curr], obj);
}
用法:
get(cars, "bentley.suppliers.0.name") // -> "Sheffield Mines"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.