ネストされたJavaScriptオブジェクト属性アクセサの文字列を解釈する最速の方法は何ですか?
-
25-10-2019 - |
質問
次のようなネストされたオブジェクト構造があるとします
var o = { a: { b: { c: 1 } } };
そして、私にはアクセサーがいます String
お気に入り "a.b.c"
.
指定されたネストされた値を(任意の深さ[1..n])返す最速の関数は何ですか?
つまり、この場合、 getNested(o, 'a.b.c') === 1
と getNested(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
(とにかく最適化される可能性があります) - 分割を置き換えます
substring
砂indexOf
s - 正規表現で分割を行います
/\./
生の文字列の代わりに"."
他のヒント
もう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')
所属していません StackOverflow