2015-01-08 2 views
1

Я хотел бы выделить конкретный объект из массива объектов на основе уникального свойства этого объекта (т. Е. Ключа).Более эффективный поиск массива

В дальнейшем, я ищу для элемента «обра», откуда ключ 8.

var myElement = arr.filter(function(element) { 
    return element.key === 8; 
}); 

Это работает, но каждый раз, когда это работает, он будет перебирать все элементы в массиве , даже после того, как найден правильный элемент. Например, если он находит myElement в индексе 4, но в массиве 100 элементов, фрагмент работает на 25 раз больше, чем нужно.

Есть ли более эффективный способ или способ прервать фильтр(), когда он нашел myElement?

Я чувствую, что я упустил что-то очевидное ...

+0

Это неправильно.Фильтр возвращает новый массив (поэтому, если вы не знаете **, у вас есть один объект, это может вернуть массив размера два с двумя объектами с ключом === 8'). Вы можете использовать простой цикл 'for'. –

+0

ключи уникальны, поэтому будет только один объект с 'element.key === 8' – davidnc

+0

см. Мой ответ, в частности вторую часть. –

ответ

1
for (var i=0; i<arr.length; i++) { 
    if (arr[i].key === 8) { 
     console.log('FOUND ITEM AT KEY '+8); 
     break; 
    } 
} 
2

Вы на самом деле хотите find функцию, которая возвращает, когда первое вхождение найдено. Вы можете использовать Array.prototype.find, если вы находитесь на ECMAScript 6 спецификации или вы можете реализовать простой find как:

function find8(arr) { 
    // type checks skipped for brevity 
    var i = 0, 
     j = arr.length; 

    for (; i < j; i++) { 
     if (arr[i].key === 8) { 
      return arr[i]; 
     } 
    } 

    throw new Error('Not found'); 
} 

Если вы хотите получить более общее решение, которое принимает предикатов (т.е. functions, которые возвращают логическое значение), вам может написать более общую функцию, как:

function find(arr, predicate) { 
    // Again, type checks skipped for brevity 
    var i = 0, 
     j = arr.length; 

    for (; i < j; i++) { 
     // Note the condition is now a call to the predicate function 
     if (predicate(arr[i])) { 
      return arr[i]; 
     } 
    } 

    throw new Error('Not found'); 
} 
1

это звучит, как вы бы лучше с чем-то вроде этого:

function findByKey(items, key) { 
    for (var index = 0; index < items.length; index++) { 
     var item = items[index]; 
     if (item.key === key) { 
      return item; 
     } 
    } 
    return null; 
} 

Обратите внимание, что если ваш список отсортирован, вы можете улучшить его, выполнив двоичный поиск. Хотя лично я предлагаю хеширование (предполагая, что один и тот же ключ не используется дважды). Что-то вроде:

var array = [/* your data here... */]; 
var map = {}; 

//do this once; or once each time your array changes 
for (var index = 0; index < array.length; index++) { 
    var item = array[index]; 
    map[item.key] = item; 
} 

//now find things by doing this 
var itemWithKey8 = map[8]; 
1

Я бы справиться с этим с помощью простого for цикла (используется функция для общего повторного использования):

function findObject(arr, cond) 
    for (i = 0; i < arr.length; i++) { 
     if (cond(arr[i]){ 
      return arr[i]; 
     } 
    } 
} 

// now call fincObject(myArray, function(element){element.key === 8}) 

Или, если вы знаете, что вы собираетесь делать это много раз, создать отображение, которое должно быть много быстрее:

function makeMapping(arr, keyFunc){ 
    var mapping = {}; 
    for (var i = 0; i < arr.length; i++) { 
     mapping[keyFunc(arr[i])] = arr[i]; 
    } 
    return mapping; 
} 

Это возвращает отображение объекта 8 к объекту с key.id === 8. Ваш keyFunc будет:

function keyFunc(element){ 
    return element.key; 
} 
0

Зачем изобретать велосипед? Здесь много подобных ответов, поэтому я поделюсь другим подходом - безусловно, моим любимым подходом. Существует отличная библиотека под названием linq.js (как автономные, так и jQuery-плагины), что делает поиск, фильтрацию, сортировку и т. Д. Ветерок.

var myElement = Enumerable.From(arr).FirstOrDefault(null,   function(element) { 
     return element.key === 8; 
}); 

В приведенном выше примере возвращается первый элемент, соответствующий условиям. Если ничего не найдено, возвращается null (первый параметр возвращает значение по умолчанию).

Смежные вопросы