元ネタ
やりたいこと
JsonObjectにobj["chino[0].cocoa.rize[2]"]
的なアプローチしたい。
値の取得だけでなく更新もしたい。
配列も使えるようにしたい
evalは嫌だ。
書いた
function access(obj, path){
path = path || '';
obj = obj || {};
var keys = path.split('.');
var value = obj;
for (var i = 0; i < keys.length; i ++) {
// List
if(keys[i].match(/^.+\[\d+\]$/)){
name = keys[i].split("[")[0];
pos = keys[i].match(/.+\[(\d+)\]/)[1];
value = value[name][pos];
// Dict
} else {
value = value[keys[i]];
}
}
return value;
}
function transform(obj, path, val){
path = path || '';
obj = obj || {};
var keys = path.split('.');
var value = obj;
path = [];
for (var i = 0; i < keys.length; i ++) {
// List
if(keys[i].match(/^.+\[\d+\]$/)){
name = keys[i].split("[")[0];
pos = keys[i].match(/.+\[(\d+)\]/)[1];
path.push(name);
path.push(pos);
if( i !== keys.length - 1){
value = value[name][pos];
}
// Dict
} else {
path.push(keys[i]);
if( i !== keys.length - 1){
value = value[keys[i]];
}
}
}
for(var i = 0; i < path.length-1; i++){
obj = obj[path[i]];
}
obj[path[path.length-1]] = val;
}
サンプル
以下のようなデータを用意した。
obj = {
"chino":
["kawaii","cappuccino"],
"cocoa" :
{
"character": "angel"
},
"rize":
{
"hair":
["angel wings", "violet"]
}
}
(1) Accessによる値の取得
access(obj,"chino[0]");
でkawaii
がとれる。
access(obj,"rize.hair[1]");
でviolet
がとれる。
(2) Transformによる値の更新
transform(obj,"chino[0]","cute");
とすると以下のようにchino[0]の値がcuteになる。
{
"chino": [
"cute",
"cappuccino"
],
"cocoa": {
"character": "angel"
},
"rize": {
"hair": [
"angel wings",
"violet"
]
}
}
もう一例。
transform(obj,"rize.hair[1]","black");
とすると
{
"chino": [
"cute",
"cappuccino"
],
"cocoa": {
"character": "angel"
},
"rize": {
"hair": [
"angel wings",
"black"
]
}
}
rizeのhairがblackになる。
辛かったこと
http://qiita.com/migi/items/3417c2de685c368faab1
にもあるが
途中は参照渡しで最後が値渡しとなるため変換されず意味不明だった。
ライセンス
使う人がいるかは不明だが一応MITライセンス。