問:JavaScript 如何查找對象中某個 value 並返迴路徑上所有的 key? 有例如上面這樣一個對象,要求封裝一個函數,傳入對象和某個 value,返回該 value 路徑上的 key。比如:searchKeys(obj, "str3"),得到 "key3, key2"。—— 來源於 @z ...
問:JavaScript 如何查找對象中某個 value 並返迴路徑上所有的 key?
let obj = {
key1: 'str1',
key2: {
key3: 'str3'
},
key4: {
key5: {
key6: 'str6',
key7: 'str7'
},
key8: 'str8'
},
key9: 'str9'
};
有例如上面這樣一個對象,要求封裝一個函數,傳入對象和某個 value,返回該 value 路徑上的 key。比如:searchKeys(obj, "str3"),得到 "key3, key2"。—— 來源於 @zanetti 的一篇 「博問」
我本想在該「博問」下作答,但是「博客園」提示我註冊尚且不滿 24 小時,不允許我回答「博問」欄目的問題。好吧,我確實是 3 月 16 日晚上剛剛註冊的「博客園」賬號,既然無法回答那就乾脆寫第一篇博客。博客的申請在 3 月 17 日早上剛剛審核通過。
言歸正傳,這題要求遍歷對象,而本質其實就是對一個多叉樹進行遞歸。
- 封裝函數並遍歷對象
第一步是最簡單的,不必多說。
function search(object, value) {
for (var key in object) {
// ...
}
}
- 必須先有結果
既然知道這裡需要遞歸,那麼最重要一點就是必須找到結果,因為沒有最終結果的遞歸操作肯定會「無法自拔」。此題,當 key 對應的值等於 value 時,遞歸就將結束,代碼如下。
if (object[key] == value) {
return [key];
} else {
}
- 然後思考遞歸
現在需要分析一下,如果沒有找到 value,object[key] 的值有哪些情況?
1、一個不等於 value 字元串;2、一個對象。
如果是一個字元串,那麼肯定是不需要任何操作,繼續下一次 for ... in 迴圈即可。如果是一個對象,那麼繼續對這個對象重覆剛剛的遍歷操作,此處即遞歸。
if (typeof(object[key]) == "object") {
var temp = search(object[key], value);
}
繼續分析(理論上腦子裡面可以假設這是倒數第二步即可)。
假如遞歸的操作並沒有找到 value,那麼返回值是什麼?我用一個 temp 變數來接收返回值,而沒有找到 value 肯定就沒有返回值,所以 temp 應該是 undefined。
假如遞歸的操作找到了 value,那麼返回值是什麼?對,是 key(這裡我為了輸出方便,使用了數組存放所有的 key)。既然得到了最後一步的 key,把他與當前的 key 放在一起即可。
if (temp == undefined) {
} else {
return [key, temp].flat();
}
這裡我是用了 flat() 方法,這個方法可以抹平一個數組。不管嵌套了多少的數組,都會展開成為一個無嵌套數組。
舉個例子:array = ["a", "b", ["c", "d"], ["e", ["f"]]] => array = array.flat() => array = ["a", "b", "c", "d", "e", "f"];
- 最終函數
function search(object, value) {
for (var key in object) {
if (object[key] == value) {
return [key];
} else if (typeof(object[key]) == "object") {
var temp = search(object[key], value);
if (temp == undefined) {
} else {
return [key, temp].flat();
}
} else {
}
}
}
再稍微修改一下。
function search(object, value) {
for (var key in object) {
if (object[key] == value) return [key];
if (typeof(object[key]) == "object") {
var temp = search(object[key], value);
if (temp) return [key, temp].flat();
}
}
}
至此,第一篇博客寫完。我接觸 JavaScript 的時間不長,也是個新手,好在這題主要是遞歸演算法,如有錯誤請在評論中指出,不勝感激!