У вас есть совет, как я могу оптимизировать обход массива javascript? - PullRequest
0 голосов
/ 22 января 2019

У меня есть несколько огромных структур массива, и я должен пройти их и прочитать некоторые ветви, а иногда мне нужно изменить некоторые листья.

Ключи массива, которые я хочу использовать, передаются в виде самого массива и генерируются где-то еще полностью разделенными.

Это мое текущее решение:

var arraytraverse = function(array, keys, value = undefined) {
  let pointer = array;
  for (let i = 0; i < keys.length; i++) {
    if (!keys.hasOwnProperty(i)) {
      continue;
    }
    if (i === keys.length - 1 && value !== undefined) {
      pointer[keys[i]] = value;
    }
    if (!pointer.hasOwnProperty(keys[i])) {
      return null;
    }
    pointer = pointer[keys[i]];
  }
  return pointer;
}

Это моеЖасмин тест:

var data = {
  a: {
    b: {
      c: {
        foo: 'bar',
      },
    },
  },
};

describe('arraytraverse', () => {

  it('should be transparent', () => {
    let res = arraytraverse(data, []);
    expect(res).toEqual(data);
  });

  it('should be traversing', () => {
    let res = arraytraverse(data, ['a', 'b']);
    expect(res).toEqual(data.a.b);
  });

  it('should handle non existing', () => {
    let res = arraytraverse(data, ['a', 'miss']);
    expect(res).toBeNull();
  });

  it('should change by reference', () => {
    arraytraverse(data, ['a', 'b', 'c', 'foo'], 'baz');
    let res = arraytraverse(data, ['a', 'b', 'c', 'foo'], 'baz');
    expect(res).toBe('baz');
    expect(data.a.b.c.foo).toBe('baz');
  });

});

Все хорошо.

Я просто хочу спросить некоторых более опытных из вас, есть ли способ улучшить мой код.

Или есть ли лучшие способы сделать это, о которых я не знаю?

И нет, я не хочу полагаться на какого-либо поставщика.Я хочу учиться.;)

TIA!

edit: я добавил некоторые изменения: pastebin.com/UkUUSAZX

1 Ответ

0 голосов
/ 22 января 2019

Нейминг

  • arraytraverse должно быть objectTraverse.
  • array должно быть object.
  • pointer может быть current? В JavaScript нет указателей!

keys - это массив

  • Если вы хотите проверить, является ли keys массивом, сделайте это в начале функции и обработайте null или undefined; проверка keys.hasOwnProperty(i) кажется странной, поскольку вы уже предполагаете, что это массив, и берете его длину Вы не проверяете это в своих тестовых случаях; и что бы вы сделали с keys как ["foo", null, "bar"]?
  • Вы можете поместить keys.length в const length = keys.length, а затем использовать это по всему коду.
  • Вы также можете сделать ++i (может быть, больше не актуально).

Последний шаг

Каждую отдельную итерацию вы проверяете, находитесь ли вы в конце массива и должны установить значение (i === keys.length - 1 && value !== undefined). Для вашего основного цикла может быть лучше сделать один шаг меньше, затем проверьте, нужно ли вставлять значение после цикла, затем, наконец, выполните последнюю разыменование current = current[keys[length - 1]] и, наконец, проверьте, существует ли оно, или верните null.

Профиль, профиль, профиль

JavaScript сильно оптимизирован в современных браузерах. Некоторые старые приемы (например, ++i) могут больше не работать, некоторые «улучшения производительности» могут фактически снизить вашу производительность в настоящее время. Чтобы проверить это, выполните правильное профилирование с большим набором данных, чтобы получить реальные метрики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...