36

javascriptでこのオブジェクトを考えてみましょう。

var obj = { a : { b: 1, c: 2 } };

文字列「obj.ab」が与えられた場合、これが参照するオブジェクトを取得して、その値を変更するにはどうすればよいですか?つまり、私は次のようなことができるようになりたい

obj.a.b = 5;
obj.a.c = 10;

ここで、「obj.ab」と「obj.ac」は文字列です(obj参照ではありません)。ドット表記文字列がobjを参照している値を取得できるこの投稿に出くわしましたが、必要なのはオブジェクト自体を取得する方法ですか?

オブジェクトのネストは、これよりもさらに深くなる可能性があります。つまり多分

var obj = { a: { b: 1, c : { d : 3, e : 4}, f: 5 } }
4

6 に答える 6

76

値を取得するには、次のことを考慮してください。

function ref(obj, str) {
    str = str.split(".");
    for (var i = 0; i < str.length; i++)
        obj = obj[str[i]];
    return obj;
}

var obj = { a: { b: 1, c : { d : 3, e : 4}, f: 5 } }
str = 'a.c.d'
ref(obj, str) // 3

または、より凝った方法で、reduceを使用します。

function ref(obj, str) {
    return str.split(".").reduce(function(o, x) { return o[x] }, obj);
}

オブジェクトメンバーへの割り当て可能な参照を返すことはjavascriptでは不可能であり、次のような関数を使用する必要があります。

function set(obj, str, val) {
    str = str.split(".");
    while (str.length > 1)
        obj = obj[str.shift()];
    return obj[str.shift()] = val;
}

var obj = { a: { b: 1, c : { d : 3, e : 4}, f: 5 } }
str = 'a.c.d'
set(obj, str, 99)
console.log(obj.a.c.d) // 99

または、ref上記を使用して、含まれているオブジェクトへの参照を取得し、それに[]演算子を適用します。

parts = str.split(/\.(?=[^.]+$)/)  // Split "foo.bar.baz" into ["foo.bar", "baz"]
ref(obj, parts[0])[parts[1]] = 99
于 2012-06-07T15:29:05.240 に答える
9

thg435の回答に似ていますが、引数がチェックされ、祖先レベルの1つがまだ定義されていないかオブジェクトではないネストレベルがサポートされます。

setObjByString = function(obj, str, val) {
    var keys, key;
    //make sure str is a string with length
    if (!str || !str.length || Object.prototype.toString.call(str) !== "[object String]") {
        return false;
    }
    if (obj !== Object(obj)) {
        //if it's not an object, make it one
        obj = {};
    }
    keys = str.split(".");
    while (keys.length > 1) {
        key = keys.shift();
        if (obj !== Object(obj)) {
            //if it's not an object, make it one
            obj = {};
        }
        if (!(key in obj)) {
            //if obj doesn't contain the key, add it and set it to an empty object
            obj[key] = {};
        }
        obj = obj[key];
    }
    return obj[keys[0]] = val;
};

使用法:

var obj;
setObjByString(obj, "a.b.c.d.e.f", "hello");
于 2013-06-07T16:30:57.727 に答える
1

これjavascriptがブラウザで実行されている場合は、次のようにオブジェクトにアクセスできます。

window['obj']['a']['b'] = 5

したがって、文字列が与えられた"obj.a.b"場合、それを次のように分割する必要があります.

var s = "obj.a.b"
var e = s.split(".")
window[e[0]][e[1]][e[2]] = 5
于 2012-06-07T15:21:15.460 に答える
0
var obj = { a : { b: 1, c: 2 } };
walkObject(obj,"a.b"); // 1

function walkObject( obj, path ){
  var parts = path.split("."), i=0, part;
  while (obj && (part=parts[i++])) obj=obj[part];
  return obj;
}

または、コードの簡潔さが好きな場合:

function walkObject( o, path ){
  for (var a,p=path.split('.'),i=0; o&&(a=p[i++]); o=o[a]);
  return o;
}
于 2012-06-07T15:29:34.770 に答える
0

オブジェクトメンバーへの割り当て可能な参照を返すことは、javascriptでは不可能です。このような1行のコードを使用して、ドット表記でディープオブジェクトメンバーに値を割り当てることができます。

new Function('_', 'val', '_.' + path + ' = val')(obj, value);

あなたの場合:

var obj = { a : { b: 1, c: 2 } };

new Function('_', 'val', '_.a.b' + ' = val')(obj, 5); // Now obj.a.b will be equal to 5
于 2015-04-11T09:55:38.960 に答える
0

以下は、簡単なクラスラッパーdictです。

class Dots(dict):
    def __init__(self, *args, **kargs):
            super(Dots, self).__init__(*args, **kargs)

    def __getitem__(self, key):
            try:
                    item = super(Dots, self).__getitem__(key)
            except KeyError:
                    item = Dots()
                    self.__setitem__(key, item)

            return Dots(item) if type(item) == dict else item

    def __setitem__(self, key, value):
            if type(value) == dict: value = Dots(value)
            super(Dots, self).__setitem__(key, value)

    __getattr__ = __getitem__
    __setattr__ = __setitem__

例:

>>> a = Dots()
>>> a.b.c = 123
>>> a.b.c
123
>>> a.b
{'c': 123}
>>> a
{'b': {'c': 123}}

欠落しているキーは、空としてその場で作成されますDots()

>>> if a.Missing: print "Exists"
...
>>> a
{'Missing': {}, 'b': {'c': 123}}
于 2015-11-16T15:03:46.343 に答える