LoginSignup
2
1

More than 5 years have passed since last update.

JavaScriptでobj["chino[0].cocoa.rize[2]"]みたいにしたメモ

Last updated at Posted at 2016-03-20

元ネタ

やりたいこと

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ライセンス。

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1