Side navigation
#809 closed enhancement (fixed)
Opened January 15, 2007 03:34PM UTC
Closed March 24, 2007 10:05PM UTC
speeding merge and inArray
Reported by: | Renato | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | 1.1.3 |
Component: | core | Version: | 1.1.1 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
I know i'm late, 1.1 has just been released :)
Here are faster versions of merge and inArray, using a reverse iterator
inArray: function( b, a ) { for ( var i = a.length; i--; ) if ( a[i] == b ) return i; return -1; }, merge: function(first, second) { var r = []; // Now check for duplicates between the two arrays // and only add the unique items for ( var i = second.length; i--; ) // Check for duplicates if ( jQuery.inArray( second[i], first ) == -1 ) // The item is unique, add it r.push( second[i] ); [].push.apply(first,r.reverse()); return first; }
In my tests they are especially good when selecting things like "div div div" or "div .class"
Attachments (0)
Change History (4)
Changed January 16, 2007 04:04PM UTC by comment:1
Changed January 16, 2007 04:06PM UTC by comment:2
Ok, this breaks up the function by it's definition. It should retain the order of the elements and the reverse looping makes it... reverse.
l = array.length, total = l;
l--;
i = total-l;
and we got the order reserved.
Further more, if we used yet another variable to keep track of the length of r and did:
r[len++] = second[i];
we could get yet faster.
The looping could be optimized yet a bit if you compare the index against 0 instead of true/false.
would first.concat(r) be faster then push and apply?
I'm in a hurry, so I can't try these out yet. I might yet something more in my stock, I've tried like 20 variations of merge so far. :)
Changed January 16, 2007 04:17PM UTC by comment:3
The order is kept reversing the elements not found in "first" before adding them to it.
concat is not an option as it makes a new array and merge has to add the elements right to the array it receives.
Consider:
//merge without getting the return value jQuery.merge(first,second);
If you use concat, first will not be affected
Changed March 24, 2007 10:05PM UTC by comment:4
milestone: | → 1.1.3 |
---|---|
need: | → Review |
resolution: | → fixed |
status: | new → closed |
version: | → 1.1.1 |
Ok, I've considerably changed how things work internally and merged some new improvements in (rev [1576]), that are quite fast.
Unfortunately, .concat() isn't an option because certain browsers (*cough*) don't know how to handle array-like objects (like NodeLists) - meaning that you have to end up looping through the results anyway. But thanks, everyone, for your help!
I realized later the speeding point is not to copy the "first" array at the beginning of merge, rather than the reverse iterator.