我在Javascript中有一個像下面這樣的物件,
const obj = {
"group1": {
"sub_group1_1": {
"inner_sub_group1_1_1": {
"name": "abc"
},
"inner_sub_group1_1_2": {
"name": "def"
}
},
"sub_group1_2": {
"inner_sub_group1_2_1": {
"name": "ghi"
},
"inner_sub_group1_2_2": {
"name": "jkl"
}
}
},
"group2": {
"sub_group2_1": {
"inner_sub_group2_1_1": {
"name": "mno"
},
"inner_sub_group2_1_2": {
"name": "pqr"
}
},
"sub_group2_2": {
"inner_sub_group2_2_1": {
"name": "stu"
},
"inner_sub_group2_2_2": {
"name": "wxy"
}
}
}
}
我想撰寫一個函式,它可以在上述物件中搜索一個鍵并回傳該鍵的相應值,例如,
輸入
filterObject(obj, 'inner_sub_group2_2_2')
輸出
{
"name": "wxy
}
輸入
filterObject(obj, 'inner_sub_group1_1_1')
輸出
{
"name": "abc
}
方法
我已經為此撰寫了一個遞回函式,但它似乎不適用于第二種情況,
const filterObject = (obj, searchedKey) => {
let result = {};
for (const key in obj) {
const currentObj = obj[key];
if (key === searchedKey) {
result = currentObj;
break;
} else if (typeof currentObj === 'object') {
result = filterObject(currentObj, searchedKey);
}
}
return result;
};
任何形式的幫助將不勝感激。謝謝!
uj5u.com熱心網友回復:
您需要能夠檢查遞回呼叫是否找到了您沒有做的事情 - 現在,您只是重新分配result,然后忽略它并繼續回圈的下一次迭代。
一種適用于這種特殊情況的方法是檢查生成的物件是否有任何鍵。
const obj={group1:{sub_group1_1:{inner_sub_group1_1_1:{name:"abc"},inner_sub_group1_1_2:{name:"def"}},sub_group1_2:{inner_sub_group1_2_1:{name:"ghi"},inner_sub_group1_2_2:{name:"jkl"}}},group2:{sub_group2_1:{inner_sub_group2_1_1:{name:"mno"},inner_sub_group2_1_2:{name:"pqr"}},sub_group2_2:{inner_sub_group2_2_1:{name:"stu"},inner_sub_group2_2_2:{name:"wxy"}}}};
const filterObject = (obj, searchedKey) => {
if (searchedKey in obj) {
return obj[searchedKey];
}
for (const key in obj) {
const currentObj = obj[key];
if (typeof currentObj === 'object') {
const result = filterObject(currentObj, searchedKey);
if (Object.keys(result).length) return result;
}
}
return {};
};
console.log(filterObject(obj, 'inner_sub_group2_2_2'));
console.log(filterObject(obj, 'inner_sub_group1_1_1'));
但是如果找到的值不是一個物件,或者找到的物件是空的,這將不起作用。(將回傳與原始結構無關的不同物件參考。)
對于更一般的情況,遞回呼叫應該回傳兩件事:是否找到嵌套值,以及找到的值(如果有)。解決此問題的一種方法是,如果找到某物,則回傳一個物件,否則不回傳。
const obj={group1:{sub_group1_1:{inner_sub_group1_1_1:{name:"abc"},inner_sub_group1_1_2:{name:"def"}},sub_group1_2:{inner_sub_group1_2_1:{name:"ghi"},inner_sub_group1_2_2:{name:"jkl"}}},group2:{sub_group2_1:{inner_sub_group2_1_1:{name:"mno"},inner_sub_group2_1_2:{name:"pqr"}},sub_group2_2:{inner_sub_group2_2_1:{name:"stu"},inner_sub_group2_2_2:{name:"wxy"}}}};
const filterObject = (obj, searchedKey) => {
if (searchedKey in obj) {
return { result: obj[searchedKey] };
}
for (const key in obj) {
const currentObj = obj[key];
if (typeof currentObj === 'object') {
const result = filterObject(currentObj, searchedKey);
if (result) return result;
}
}
};
console.log(filterObject(obj, 'inner_sub_group2_2_2').result);
console.log(filterObject(obj, 'inner_sub_group1_1_1').result);
uj5u.com熱心網友回復:
您的代碼中的問題是,如果遞回呼叫成功,則回圈仍會繼續,并進行另一個可能不成功的遞回呼叫,因此result會丟失好東西。
您需要if在該遞回呼叫之后檢測成功并在成功時中斷。
現在,為了區分失敗和成功,如果null在沒有成功的情況下回傳,事情會變得容易得多。
需要調整兩行:
const filterObject = (obj, searchedKey) => {
let result = null; // To indicate nothing found yet
for (const key in obj) {
const currentObj = obj[key];
if (key === searchedKey) {
result = currentObj;
break;
} else if (typeof currentObj === 'object') {
result = filterObject(currentObj, searchedKey);
if (result) break; // <--- break out when success!
}
}
return result;
};
你的 is-object 測驗可能需要一點改進,因為typeof null === 'object'它是一個真實的運算式。
您可以改用它:
if (Object(currentObj) === currentObj)
uj5u.com熱心網友回復:
這是@trincot 和@certainperformance 的答案的變體。根本沒有什么新東西,只是風格略有不同:
const obj={group1:{sub_group1_1:{inner_sub_group1_1_1:{name:"abc"},inner_sub_group1_1_2:{name:"def"}},sub_group1_2:{inner_sub_group1_2_1:{name:"ghi"},inner_sub_group1_2_2:{name:"jkl",spoiler:null}}},group2:{sub_group2_1:{inner_sub_group2_1_1:{name:"mno"},inner_sub_group2_1_2:{name:"pqr",xtr:false}},sub_group2_2:{inner_sub_group2_2_1:{name:"stu"},inner_sub_group2_2_2:{name:"wxy"}}}};
function flto(obj,k,r){
if(!(obj&&typeof obj=="object")) return null;
if(k in obj) return obj[k];
for(l in obj) if((r=flto(obj[l],k))!=null) break;
return r
}
console.log(['inner_sub_group2_2_2','inner_sub_group1_1_1','xtr'].map(k=>flto(obj,k)));
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/486006.html
標籤:javascript 数组 目的
