2017-04-10 11 views
2

連想配列のキーの存在をどのくらい正確にチェックするか教えてください。例えば連想配列のキーの存在を確認する

:私は

safeSet(mydata.key2.subkey1.subkey1_1.value1, 'test'); 

または

if (is_undefined(mydata.key2.subkey1.subkey1_1.value1) == true) 
    mydata.key2.subkey1.subkey1_1.value1 = 'test'; // now - error if 'mydata.key2.subkey1.subkey1_1' not exist 
のように、単純な機能を使用したい

((mydata.key2 != undefined) && (mydata.key2.subkey1 != undefined) && (mydata.key2.subkey1.subkey1_1 != undefined)) 

var mydata = { 
    key1: '', 
    key2: { 
     subkey1: { 
      subkey1_1: { 
       value1: '' 
       value2" '', 
      }, 
     }, 
     subkey2: ''; 
    }, 
} 

if ((mydata.key2 != undefined) && (mydata.key2.subkey1 != undefined) && (mydata.key2.subkey1.subkey1_1 != undefined)) 
    mydata.key2.subkey1.subkey1_1.value1 = 'test'; 

長すぎると混乱

"key" in obj // true, regardless of the actual value 

をそれとも、あなたがオブジェクトインスタンスのプロパティ(および継承されない性質)のために特にテストする場合、これは希望hasOwnProperty:

obj.hasOwnProperty("key") // true 

希望を使う:

+3

'associative arrays'?あなたは ''オブジェクト ''を意味する –

+0

キーが存在するか、キーに値があるかどうかチェックしますか?あなたの質問は前者を、あなたのコードは後者を意味します。どちらの方法でも、 'try/catch'ブロックを使うことができるように聞こえます。 –

答えて

2

あなたは、ネストされたプロパティが存在するかどうかをテストするreduce()を使用してカスタム関数を作成することができます。あなたは単に文字列としてキーを渡すことができます。

var mydata = { 
 
    key1: '', 
 
    key2: { 
 
    subkey1: { 
 
     subkey1_1: { 
 
     value1: '', 
 
     value2: '', 
 
     }, 
 
    }, 
 
    subkey2: '' 
 
    }, 
 
} 
 

 
function safeSet(key, data) { 
 
    return key.split('.').reduce(function(r, e) { 
 
    return r ? r[e] : undefined; 
 
    }, data) != undefined 
 
} 
 

 
console.log(safeSet('key2.subkey1.subkey1_1.value1', mydata))

0

私はこのような何かをしたい入れ子構造で何かを取得しようとしている場合:もちろん

function getPath(element, path) { 
    var handledSoFar = []; 
    for (var i = 0; i < path.length; i++) { 
     var property = path[i]; 
     handledSoFar.push(property); 
     if (typeof element[property] === 'undefined') { 
      throw new Error('Path ' + handledSoFar.join('->') + ' is undefined'); 
     } 
     element = object[property]; 
    } 
    return element; 
} 

var mydata = { 
    key1: '', 
    key2: { 
     subkey1: { 
      subkey1_1: { 
       value1: '', 
       value2: 'hi' 
      } 
     }, 
     subkey2: '' 
    } 
}; 

// Prints 'hi' 
console.log(getPath(mydata, ['key2', 'subkey1', 'subkey1_1', 'value2'])); 

// Throws error 'Path key2->subkey2->subkey1_1 is undefined' 
console.log(getPath(mydata, ['key2', 'subkey1', 'subkey1_1', 'value2'])); 

handledSoFarで検索を追跡し、オプションであるかもしれませんが、開発/デバッグに便利です。

1

また、.has()メソッドをLodashにすることもできます。 次に、あなただけをチェックする必要があります:

if (_.has(mydata, 'key2.subkey1.subkey1_1.value1') 
    mydata.key2.subkey1.subkey1_1.value1 = 'test'; 
0

あなたはまた、lodash深いフィールドセレクタを使用することができます:lodash.getdocumentation)あなたがパスを分割することができ

const get = require('lodash.get'); 
const set = require('lodash.set'); 

if (!get(mydata, 'key2.subkey1.subkey1_1.value1')) { 
    set(mydata, 'key2.subkey1.subkey1_1.value1', 'test'); 
} 
0

をしてチェックを行い、以下の場合要素が存在する。新しいプロパティにオブジェクトを割り当てない場合。

プロパティの値を返します。

最後に値を割り当てます。

function setValue(object, path, value) { 
 
    var fullPath = path.split('.'), 
 
     way = fullPath.slice(), 
 
     last = way.pop(); 
 

 
    way.reduce(function (r, a) { 
 
     return r[a] = r[a] || {}; 
 
    }, object)[last] = value; 
 
} 
 

 
var object = { key1: '', key2: { subkey1: { subkey1_1: { value1: '', value2: '' } }, subkey2: '' } }; 
 

 
setValue(object, 'key2.subkey1.subkey1_1.value1', 'test'); 
 
console.log(object);

0

あなたが提案した例の機能に問題:

safeSet(mydata.key2.subkey1.subkey1_1.value1, 'test'); 

または

is_undefined(mydata.key2.subkey1.subkey1_1.value1) 

はmydata.key2.subkey1ということです...一部の前に実行されます。関数が呼び出されます。したがって、サブキーの1つが存在しない場合、コードに達する前に例外がスローされます。

safeSetの実装は次のようになり

safeSet(function(val) { mydata.key2.subkey1.subkey1_1.value1 = val; }, 'test') 

あなたはしかし、コールバックを使用して、同様の何かを得ることができ

...:

var safeSet = function(setterFunc, val) { 
    try { 
    setterFunc(val); 
    } catch (e) { 
    if (e instanceof TypeError) { 
     return false; 
    } else { 
     throw e; 
    } 
    } 
    return true; 
} 

safeSetは値が設定された場合はtrueを返し、そうでない場合はfalse 。

関連する問題