Задать вопрос
Kozack
@Kozack
Thinking about a11y

Какой самый быстрый способ поиска по массиву объектов?

Существует массив объектов вида:

[{
    id:123,
    name: 'Name1'
},{
    id: 321,
    name: 'Name2'
}]

Какой самый быстрый способ поиска элемента массива по заданному id?
Как вариант рассматривал перевести массив в объект:

{
  123: {
    id:123,
    name: 'Name1'
  },
  321: {
    id: 321,
    name: 'Name2'
  }
}

Но проблема в том, что в процессе работы приложения данный массив постоянно изменяется: добавляются и удаляются новые элементы, а также свойства отдельных элементов. И приходится каждый раз при изменении массива заново создавать индексированный объект. Поэтому ищу альтернативу.
  • Вопрос задан
  • 959 просмотров
Подписаться 1 Оценить 2 комментария
Решения вопроса 1
Если в проекте используется jQuery то, думаю, есть смысл обратиться к jQuery.grep:
var source = [{
    id:123,
    name: 'Name1'
  },{
    id: 321,
    name: 'Name2'
  }];

function getObject(source, id) {
	return jQuery.grep(source, function(e){ return e.id == id; });
}

console.log(getObject(source, 321));


Если массив не очень большой, то простого перебора возможно будет вполне достаточно:
function getObject(source, id) {
  for (var i = 0, len = source.length; i < len; i++) {
    if (source[i].id == id) {
      return source[i];
    }
  }
}

Если есть возможность использовать ECMAScript 6, то можно обратиться к его нативной функции (для "старых" браузеров можно подключить этот полифил):
function getObject(source, id) {
  return source.find(function (el) {
    return el.id === id;
  });
}

Или прибегнуть к хорошо поддерживаемому методу filter:
function getObject(source, id) {
  return source.filter(function(el) {
    return el.id === id;
  })[0];
}


Какой из методов покажет покажет себя лучше у вас - тот и используйте. Для тестов просто прогоните каждый, например, так:
console.time('test_func_exec');
for (var i = 0; i < 10000000; i++) {
  getObject(source, 123);
}
console.timeEnd('test_func_exec');

Запустив каждый с десяток раз на "боевых" данных, и взяв среднее время выполнения каждого (тестирование, как я полагаю, вы будете производить в браузере).
Хорошего вам дня!
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
О каком размере массива идёт речь? Если <1000 элементов - array.filter будет вполне достаточно.
Если больше - можно хранить пары {id -> element} в объекте. По сути вам нужно будет только добавлять новый элемент в хеш или удалять из хеша удаленный.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы