これを解決するためには、以下のようなクソダサ実装をしなければならない。
if (obj && obj.parent && obj.parent.child && obj.parent.child.grandchild) {
// ここでようやく安全にobj.parent.child.grandchildにアクセスできる
}
あまりにもクサくて、ダサすぎる…。
今は4階層だが、これが長いキーだったり、もっと階層が深かったりすると見ていられない。
ということで、ネストされたObjectのキーが存在するかどうかチェックする方法を考えてみた。
ネストされたObjectのキーをチェックする
以下のようなオブジェクトがあるとする。
// object
const obj = {
parent: {
child: {
grandchild: 'あるよ',
grandchild1: '1',
grandchild2: '2'
},
child2: {}
}
};
const lookup = function _lookup (obj, path) {
const keys = path.split('.');
for (let k in keys) {
const key = keys[k];
if (!obj.hasOwnProperty(key)) { return false; }
if (keys.length > 1) {
return _lookup(obj[key], keys.splice(1).join('.'));
}
return true;
}
};
// テスト
console.log( lookup(obj, 'parent') ); // -> true
console.log( lookup(obj, 'parent1') ); // -> false
console.log( lookup(obj, 'parent.child') ); // -> true
console.log( lookup(obj, 'parent.child2') ); // -> true
console.log( lookup(obj, 'parent.hoge') ); // -> false
console.log( lookup(obj, 'parent.child.grandchild') ); // -> true
console.log( lookup(obj, 'parent.child.grandchild1') ); // -> true
console.log( lookup(obj, 'parent.child.huga') ); // -> false
lookup(obj, 'path')のように呼び出すことで、キーが存在すればtrue、なければfalseになる。
やっていることは、渡されたpath(parent.child.grandchild)分ループして、オブジェクトに存在するかどうかをobj.hasOwnProperty()で確認し、それを再帰的に呼び出しているだけ。
ちなみに、lodashを導入すれば_.get(obj, 'parent.child.grandchild')で該当するキーの値を取得できる。(実装し終わってからあることに気づいた…)
以上
written by @bc_rikko
0 件のコメント :
コメントを投稿