Какой самый быстрый способ интерпретировать вложенную строку метода доступа к атрибуту объекта javascript? - PullRequest
1 голос
/ 18 октября 2011

Скажем, у меня есть структура вложенного объекта, например:

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?

Ответы [ 5 ]

4 голосов
/ 18 октября 2011

еще один вариант:

function getNested(obj, path) {
  path.replace(/[^\.]+/g, function (p) {
    obj = obj[p];
  });
  return obj;
}
2 голосов
/ 18 октября 2011

Я не хочу давать ответ без профилирования кода сам, но, учитывая, что eval, вероятно, медленный, а forEach медленнее, чем просто выполнение цикла for, я бы начал с:

// 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 была бы полезной, но это только одна вещь, которую вы можете попробовать, если вызаинтересованы в самом быстром способе.

ADDENDUM

Вот расшифровка, так что вы можете увидеть ее в действии:

$ 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

** ADDENDUM 2 **

Так стыдно - я забыл var перед result раньше.Это может немного ускорить процесс!

Другие вещи, которые можно попробовать:

  • Забудьте об «оптимизации» с помощью n и просто выполните тест цикла for с помощью i < test.length(в любом случае может быть оптимизирован)
  • Замените разделение на substring s и indexOf s
  • Выполните разделение с помощью регулярного выражения /\./ вместо необработанной строки "."
1 голос
/ 18 октября 2011
try{
   var prop=eval(string);
}
catch(er){
   prop=undefined;
}
1 голос
/ 18 октября 2011

Может быть, что-то вроде этого:

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

Возможно, это не самое быстрое решение, но может быть полезной отправной точкой.

0 голосов
/ 29 января 2013

Мой подход

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')
...