ネストされたJavaScriptオブジェクト属性アクセサの文字列を解釈する最速の方法は何ですか?

StackOverflow https://stackoverflow.com/questions/7803246

質問

次のようなネストされたオブジェクト構造があるとします

var o = { a: { b: { c: 1 } } };

そして、私にはアクセサーがいます String お気に入り "a.b.c".

指定されたネストされた値を(任意の深さ[1..n])返す最速の関数は何ですか?

つまり、この場合、 getNested(o, 'a.b.c') === 1getNested(o, 'a') === {b:{c:1}}.

の最良の実装は何ですか getNested?

役に立ちましたか?

解決

コードを自分でプロファイリングせずに答えを出すのは嫌いですが、それを考えると eval おそらく遅いです、そして forEach for-loopを駆け抜けるよりも遅いので、私は以下から始めます。

// precondtion: path is a nonempty string
function getNested(obj, path) {
    var fields = path.split(".");
    var result = obj;
    for (var i = 0, n = fields.length; i < n; i++) {
        result = result[fields[i]];
    }
    return result;
}

しかし、私はこれを他のアプローチに対してテストします。

アレイの構造を最適化しようとしているとは思わない split 価値があるでしょうが、これはあなたが興味を持っているなら試してみるのに一つのことです 最速の方法。

補遺

これがトランスクリプトですので、あなたはそれを動作しているのを見ることができます:

$ node
> function getNested(obj, path) {
...     var fields = path.split(".");
...     var result = obj;
...     for (var i = 0, n = fields.length; i < n; i++) {
...         result = result[fields[i]];
...     }
...     return result;
... }
> var o = { a: { b: { c: 1 } } };
> getNested(o, "a")
{ b: { c: 1 } }
> getNested(o, "a.b.c")
1

**補遺2 **

とても恥ずかしい - 私は忘れた var の前に result 前。それは少しスピードアップするかもしれません!

試してみる他のこと:

  • 「最適化」を忘れてください n そして、for-loopテストを使用してください i < test.length (とにかく最適化される可能性があります)
  • 分割を置き換えます substringindexOfs
  • 正規表現で分割を行います /\./ 生の文字列の代わりに "."

他のヒント

もう1つのバリアント:

function getNested(obj, path) {
  path.replace(/[^\.]+/g, function (p) {
    obj = obj[p];
  });
  return obj;
}

多分このようなもの:

function getNested(o, path) {
    var parts = path.split('.');
    var member = o;
    while (member && parts.length) {
        member = member[parts.shift()];
    }
    return member;
}

おそらく可能な限り最速のソリューションではありませんが、有用な出発点かもしれません。

try{
   var prop=eval(string);
}
catch(er){
   prop=undefined;
}

私のアプローチ

var o = { a: { b: { c: 1 } } };
var getNested = function(p) {
    var t;
    p.split('.').forEach(function(e) {
        t = o[e] || t[e]
    });
    return t
}

あなたが試すことができます:

getNested('a.b.c')
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top