Reputation: 5547
I have an array of javascript objects containing about 6300 elements.
I am trying to use jQuery to iterate through those elements and create lists of options for several drop-down lists that can be used to filter those 6300 elements.
In Firefox, this works with no problem, but in IE, I get an error about the script running slow. I've been playing with the code trying to get a set of the data without causing that IE error, but so far, I've had no luck. Below are the methods I have already tried:
Using "indexOf" to create a distinct list of "Jurisdictions".
var arrayJurisdiction = dataSet.filter(function (item, i, a) {
return i.Jurisdiction == a.indexOf(item.Jurisdiction);
});
Iterating over each element, checking to see if the value already exists in the secondary array, and if it doesn't, then adding it.
g$.each(dataSet, function (key, value) {
var matchingJurisdiction = arrayJurisdiction.filter(function (item) {
return value.Jurisdiction == item;
})[0];
if (matchingJurisdiction == null) {
arrayJurisdiction.push(value.Jurisdiction);
}
});
Both of these methods result in IE giving me an error about a script running too slowly. Is there any faster way of doing this?
*EDIT*** Based on feedback below, I have changed the method to use for loops instead of .each() and .filter(), but I am still receiving the "stop this script?" dialog in IE.
Here is the revised code, using the for loops. Also, I have included all the filters I am attempting to fill (not just the first one).
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);
}
}
Upvotes: 0
Views: 2307
Reputation: 10221
Dropping jQuery each()
is certainly an option as it does some funny stuff with the scope beside actual iteration. Another real is that your algorithm seem to be O(n^2) which is pretty bad. I would simply sort your dataSet
on Jurisdiction
value, and then loop over keeping previous value and eliminating duplicates. That is going to be the O of the sort algorithm, which is likely using quick sort algorithm O(n*log(n)), but is also likely implemented much more efficiently in native code.
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];
}
Upvotes: 1