I have multiple arrays with string values and I want to compare them and only keep the matching results that are identical between ALL of them.
Given this example code:
var arr1 = ['apple', 'orange', 'banana', 'pear', 'fish', 'pancake', 'taco', 'pizza'];
var arr2 = ['taco', 'fish', 'apple', 'pizza'];
var arr3 = ['banana', 'pizza', 'fish', 'apple'];
I would like to to produce the following array that contains matches from all given arrays:
['apple', 'fish', 'pizza']
I know I can combine all the arrays with var newArr = arr1.concat(arr2, arr3);
but that just give me an array with everything, plus the duplicates. Can this be done easily without needing the overhead of libraries such as underscore.js?
(Great, and now i'm hungry too!)
EDIT I suppose I should mention that there could be an unknown amount of arrays, I was just using 3 as an example.
Now, that you've added an indeterminate number of arrays to the question, here's another approach that collects the count for each item into an object and then collates the items that have the max count.
Advantages of this approach:
And here's the code:
Working demo: http://jsfiddle.net/jfriend00/52mAP/
FYI, this does not require ES5 so will work in all browsers without a shim.
In a performance test on 15 arrays each 1000 long, this was more than 10x faster than the search method used in am not i am's answer in this jsperf: http://jsperf.com/in-all-arrays.
Here's a version that uses an ES6
Map
andSet
to de-dup and keep track of counts. This has the advantage that the type of data is preserved and can be anything (it doesn't even have to have a natural string conversion, the data can even be objects though objects are compared for being the exact same object, not having the same properties/values).Assuming there is an array of arrays those we want to find the intersection of, a simplest single liner approach could be
DEMO: http://jsfiddle.net/nWjcp/2/
You could first sort the outer Array to get the shortest Array at the beginning...
For completeness, here's a solution that deals with duplicates in the Arrays. It uses
.reduce()
instead of.filter()
...DEMO: http://jsfiddle.net/nWjcp/4/
Just for the heck of it, another long hand approach:
Edit
Function to find never enumerable properties based on thise on Object.prototype:
Here goes a single-line solution. You can split it into two thinking steps:
A couple thoughts- you can compare just the items in the shortest array, and prevent duplicates in the returned array.
returned value:
apple,fish,pizza
DEMO - http://jsfiddle.net/kMcud/