Skip to content

Instantly share code, notes, and snippets.

@matthewkastor
Created January 23, 2013 06:21
Show Gist options
  • Save matthewkastor/4602551 to your computer and use it in GitHub Desktop.
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
/**
* 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;
}
/**
* 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