2012-01-13 2 views
0

У меня есть массив объектов javascript, содержащий около 6300 элементов.Функция jquery .filter() на большом массиве медленна в IE

Я пытаюсь использовать jQuery для итерации по этим элементам и создания списков параметров для нескольких раскрывающихся списков, которые можно использовать для фильтрации этих 6300 элементов.

В Firefox это работает без проблем, но в IE возникает ошибка в медленном запуске скрипта. Я играл с кодом, пытаясь получить набор данных, не вызывая ошибки IE, но до сих пор мне не повезло. Ниже приведены методы, которые я уже пробовал:

Использование «indexOf» для создания отдельного списка «Юрисдикции».

var arrayJurisdiction = dataSet.filter(function (item, i, a) { 
     return i.Jurisdiction == a.indexOf(item.Jurisdiction); 
    }); 

итерации по каждому элементу, проверяя, если значение уже существует во вторичном массиве, и если это не так, то добавлять его.

g$.each(dataSet, function (key, value) { 
     var matchingJurisdiction = arrayJurisdiction.filter(function (item) { 
      return value.Jurisdiction == item; 
     })[0]; 
     if (matchingJurisdiction == null) { 
      arrayJurisdiction.push(value.Jurisdiction); 
     } 
    }); 

Оба эти метода приводят к тому, что IE дает мне ошибку в том, что скрипт работает слишком медленно. Есть ли более быстрый способ сделать это?

* EDIT *** На основе обратной связи ниже, я изменил метод, используемый для петель вместо .each() и .filter(), но я все еще получаю «стоп этого сценария ?» диалог в IE.

Вот пересмотренный код с использованием циклов for. Кроме того, я включил все фильтры, которые я пытаюсь заполнить (а не только первый).

for (var i = 0; i < dataSet.length; i++) { 
     var value = dataSet[i]; 

     var matchingJurisdiction = null; 
     for (var i = 0; i < arrayJurisdiction.length; i++) { 
      var item = arrayJurisdiction[i]; 
      if (item == value.Jurisdiction) { 
       matchingJurisdiction == item; 
       break; 
      } 
     } 
     if (matchingJurisdiction == null) { 
      arrayJurisdiction.push(value.Jurisdiction); 
     } 



     var valueYear = new Date(value.Treatment_Date).getFullYear(); 
     var matchingYear = null; 
     for (var i = 0; i < arrayYear.length; i++) { 
      var item = arrayYear[i]; 
      if (item == valueYear) { 
       matchingYear == item; 
       break; 
      } 
     } 

     if (matchingYear == null) { 
      arrayYear.push(valueYear); 
     } 
     var matchingProjectClass = null; 
     for (var i = 0; i < arrayProjectClass.length; i++) { 
      var item = arrayProjectClass[i]; 
      if (item == valueYear) { 
       matchingProjectClass == item; 
       break; 
      } 
     } 
     if (matchingProjectClass == null) { 
      arrayProjectClass.push(value.Project_Classification); 
     } 

     var matchingImprovementType = null; 
     for (var i = 0; i < arrayImprovementType.length; i++) { 
      var item = arrayImprovementType[i]; 
      if (item == valueYear) { 
       matchingImprovementType == item; 
       break; 
      } 
     } 
     if (matchingImprovementType == null) { 
      arrayImprovementType.push(value.Improvement_Type); 
     } 
    } 
+2

Если скорость ваша цель, то первое, что вы должны сделать, это переключиться на цикл, без вызова функции, а не '.filter()' и '.each()'. – jfriend00

+0

Ваша цель просто объединить два массива? Если это так, и ваши массивы большие, вы найдете это намного быстрее, если вы используете объект для хранения элементов в массиве, поскольку 'a в obj' будет намного быстрее, чем' arr.indexOf (a) 'для больших массивы. (Где 'a' - это то, что вы пытаетесь найти,' obj' - это объект со значениями в виде ключей, а 'arr' - массив объектов.) –

+0

Если бы вы могли описать, какие значения данных у вас есть и что вы «Попытка сделать людей может, вероятно, предложить гораздо лучший код, возможно, используя объект в качестве справочной таблицы. Но я не могу полностью понять, какие данные у вас есть и что вы пытаетесь выполнить из коротких фрагментов кода. Все, что вызывает .indexOf многократно в цикле, вероятно, должно быть заменено поиском объекта, даже если это означает, что препроцесс проходит для создания объекта. – jfriend00

ответ

1

капают JQuery each() это, конечно, вариант, как это делает некоторые смешные вещи с областью рядом с фактической итерации. Другое реальное заключается в том, что ваш алгоритм кажется O (n^2), что довольно плохо. Я просто сортирую ваше значение dataSet по значению Jurisdiction, а затем перебираю предыдущее значение и исключаю дубликаты. Это будет алгоритм сортировки O, который, скорее всего, использует алгоритм быстрой сортировки O (n * log (n)), но, скорее всего, будет реализован гораздо более эффективно в собственном коде.

dataSet.sort(function(a, b) 
{ 
    if (a.Jurisdiction > b.Jurisdiction) 
     return 1; 
    if (a.Jurisdiction < b.Jurisdiction) 
     return -1; 
    return 0; 
}); 

var prev = null; 
var filtered = new Array(dataSet.length); 
for (var i=0; i<dataSet.length; i++) 
{ 
    if (prev == null || prev.Jurisdiction != dataSet[i].Jusrisdiction) 
     filtered.push(dataSet[i]); 
    prev = dataSet[i]; 
} 
+0

+1 для сортировки. – Gabe

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