🙆
ネストしたオブジェクトからキー指定で値を取り出したかった覚書
動機
再帰で脳筋実装しても良いけど、なんとなくreduce使いたかった
やりたかった事
let data = {b: 500, g:{value: 30}, c:[32]}
こっから
let keys = ["g", "value"]
配列で探索パスを指定すると
search(data, keys)
// -> 30
値が取り出せる。
ゆるふわ実装
function search(data,keys){
return keys.reduce((current, key) => {
try{
return current[key]
} catch(e) {
return undefined
}
}, data)
}
ぱっと見、クロージャで再帰してるのとそんなに変わらない
テストしてみる
できたっぽいのでテストしてみる
オブジェクトキーで探索
data = {b: 500, g:{value: 30}, c:[32]}
keys = ["b"];
search(data, keys);
// -> 500
ネストされたオブジェクトを探索
data = {b: 500, g:{value: 30}, c:[32]}
keys = ["g", "value"]
search(data, keys)
// -> 30
ネストされたオブジェクト/配列を探索
data = {b: 500, g:{value: 30}, c:[32]}
keys = ["c", 0]
search(data, keys)
// -> 32
キーが存在しなければundefined返す
data = {b: 500, g:{value: 30}, c:[32]}
keys = ["c", 100]
search(data, keys)
// -> undefined
まとめ
良い感じに動いた。
Discussion
以前、こちらの記事を書いたことがあります。
JavaScript オブジェクトの深くネストされているプロパティに安全にアクセスする getProperty - Qiita
やっていることは同じですが、
オブジェクトのプロパティパスを文字列指定してsplit('.')しています。
search関数は、存在判定にtry catch の例外を挟むのはちょっと動作コストがかさみそうでしたので、次のようにしてもいいのかもと思いました。
なるほど。意図的に例外挟んじゃうとコスト重くなっちゃうんですね。
予測可能な場合は真面目に分岐を書くようにします!