Created
January 23, 2013 06:21
-
-
Save matthewkastor/4602551 to your computer and use it in GitHub Desktop.
JavaScript Array intersection functions. Check out the performance tests at http://jsperf.com/nopub/2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* See: http://stackoverflow.com/a/1885766 | |
* | |
* Note: because this function transfers array values | |
* to an object's properties, the result set will consist | |
* of unique values. Given [1,2,3,3] and [3,3,4,5] this | |
* function will return [3]. | |
* | |
* This function attempts to avoid doing extra work | |
* by assigning all values from the array given as | |
* argument 'b' as properties on an intermediate | |
* object 'd'. At this point, all values in 'b' have | |
* been observed and no decision has been made as | |
* to whether or not said values are part of the | |
* intersection of the sets. The next step is to | |
* cycle through every element of the array given | |
* as argument 'a' and compare it to the properties | |
* present in 'd'. If the value being observed in 'a' | |
* corresponds to a property present in 'd' then | |
* that value will be pushed into the output array. | |
* This method ensures that every element of both | |
* arrays will be observed. The quantity of observations | |
* may be calculated by the sum of the input arrays | |
* lengths. | |
* | |
* Given two input arrays with lengths of 1000 and 10, | |
* this function will make 1010 observations. | |
*/ | |
function intersect(a, b) { | |
var d = {}; | |
var results = []; | |
for (var i = 0; i < b.length; i++) { | |
d[b[i]] = true; | |
} | |
for (var j = 0; j < a.length; j++) { | |
if (d[a[j]]) | |
results.push(a[j]); | |
} | |
return results; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* finds the intersection of | |
* two arrays in a simple fashion. | |
* | |
* see : http://stackoverflow.com/a/1885660 | |
* | |
* PARAMS | |
* a - first array, must already be sorted | |
* b - second array, must already be sorted | |
* | |
* NOTES | |
* | |
* Should have O(n) operations, where n is | |
* n = MIN(a.length(), b.length()) | |
* | |
* Note that if the input arrays contain multiple identical | |
* intersecting elements that they will be returned. This | |
* means that the result set is not guaranteed to contain | |
* unique values. Given [1,3,3,4] and [1,2,3,3] the result | |
* will be [1,3,3]. | |
* | |
* This function relies on the arrays being sorted | |
* before being called to find the intersection of | |
* sets of values stored in them. It guards against | |
* doing any extra work by basically sliding the | |
* ordered values side by side in the same direction, | |
* the sliding of one set or another being dependent | |
* upon the equality of the two elements observed just | |
* prior to the action. This method ensures that the | |
* consistent amount of elements processed from each set | |
* will be equal to the lesser of both array's lengths | |
* summed with the quantity of observations for which | |
* no intersection was found. The quantity of observations | |
* will not exceed the greater of the lengths of the | |
* input arrays. | |
* | |
* When given two arrays with lengths of 1000 and 10, | |
* this function will make at least 10 observations and | |
* at most 1000 observations. | |
* These first ten observations are immediately compared | |
* and if they happen to all show the intersection of sets | |
* then this function will return the intersecting set and | |
* exit immediately. If the 9th observation should happen | |
* to be made with one element not belonging to the | |
* intersecting set then this element will be compared to | |
* the remaining unknown elements of the other set until | |
* it is observed that it has passed a point of that | |
* ordered set where it would have intersected. i.e. 9 | |
* will be compared with 6, 7, and 10, at which point | |
* it will be determined to belong outside of the | |
* intersection and will be discarded. The 10th | |
* element will then be compared to that same element (10). If | |
* there is a match then the 10th element will be added to | |
* the intersecting set and the function will return. If it | |
* does not match then the process continues on. | |
*/ | |
function intersect_safe(a, b) | |
{ | |
var ai=0, bi=0; | |
var result = new Array(); | |
while( ai < a.length && bi < b.length ) | |
{ | |
if (a[ai] < b[bi] ){ ai++; } | |
else if (a[ai] > b[bi] ){ bi++; } | |
else /* they're equal */ | |
{ | |
result.push(a[ai]); | |
ai++; | |
bi++; | |
} | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment