解決
の構文str
が正しいことが確実な場合、関数は次のようになります。
function get_by_path(source, path){
var path_elements = path.split(']').join('').split('[');
for (var i=0; i < path_elements.length; i++){
source = source[path_elements[i]];
if (typeof source === 'undefined'){
return null;
}
};
return source;
};
テスト
動作は次のとおりです。
var data = {'user': {
'username': "AzureDiamond", 'password': "hunter2",
'details': {'address': {'street': "Happiness Street"}}
}};
get_by_path(data, 'user'); // gives user object
get_by_path(data, 'user[username]'); // gives "hunter2"
get_by_path(data, 'user[password]'); // gives "AzureDiamond"
get_by_path(data, 'fake'); // gives null
get_by_path(data, 'user[details][address][street]'); // gives "Happiness Street"
説明
スクリプトは正規表現も危険な呼び出しも使用せず、「パス」は角かっこなしの1つの単語で始まり、次のすべての部分(存在する場合)は角かっこで囲まれた単語であるとeval()
想定します。トラバースされたオブジェクト内にパスが見つからない場合は、が返されます。見つかった場合は、返されます(複雑なオブジェクト、文字列、ブール値などに関係なく)。null
null
スクリプトは、パスを解析することから始まります。これは、閉じ角かっこ( " ]
")を削除し、角かっこ( "")を開いて結果の文字列を分割することによって行われます[
。プロセスは次のようになります。
"user" -> "user" -> ["user"]
"user[username]" -> "user[username" -> ["user", "username"]
"user[password]" -> "user[password" -> ["user", "password"]
"user[address][street]" -> "user[address[street" -> ["user", "address", "street"]
"fake" -> "fake" -> ["fake"]
したがって、ご覧のとおり、最後にパス要素の配列があります。これらは1つずつ評価されます。いずれかのレベルで適切なステップをデータ引数の構造に深く入れることができない場合は、null
が返されます。それ以外の場合は、最後にアクセスされた要素が返されます。
証拠
それが機能することの証明はここにあります:http://jsfiddle.net/EJCgE/2/
編集replace()
:文字列のメソッドがどのように機能するかに起因して、より複雑なパス(3つ以上のレベルがある場合)にいくつかの問題がありました。jQueryを含まないようにコードを更新し、その問題を修正しました。
EDIT2:冗長な行と1つの冗長な変数を削除するようにスクリプトを更新しました。