You could just use Array#reduce with Array#filter and Array#includes.
var array1 = ["Lorem", "ipsum", "dolor"],
array2 = ["Lorem", "ipsum", "quick", "brown", "foo"],
array3 = ["Jumps", "Over", "Lazy", "Lorem"],
array4 = [1337, 420, 666, "Lorem"],
data = [array1, array2, array3, array4],
result = data.reduce((a, b) => a.filter(c => b.includes(c)));
console.log(result);
Answer from Nina Scholz on Stack OverflowYou could just use Array#reduce with Array#filter and Array#includes.
var array1 = ["Lorem", "ipsum", "dolor"],
array2 = ["Lorem", "ipsum", "quick", "brown", "foo"],
array3 = ["Jumps", "Over", "Lazy", "Lorem"],
array4 = [1337, 420, 666, "Lorem"],
data = [array1, array2, array3, array4],
result = data.reduce((a, b) => a.filter(c => b.includes(c)));
console.log(result);
I wrote a helper function for this:
function intersection() {
var result = [];
var lists;
if(arguments.length === 1) {
lists = arguments[0];
} else {
lists = arguments;
}
for(var i = 0; i < lists.length; i++) {
var currentList = lists[i];
for(var y = 0; y < currentList.length; y++) {
var currentValue = currentList[y];
if(result.indexOf(currentValue) === -1) {
var existsInAll = true;
for(var x = 0; x < lists.length; x++) {
if(lists[x].indexOf(currentValue) === -1) {
existsInAll = false;
break;
}
}
if(existsInAll) {
result.push(currentValue);
}
}
}
}
return result;
}
Use it like this:
intersection(array1, array2, array3, array4); //["Lorem"]
Or like this:
intersection([array1, array2, array3, array4]); //["Lorem"]
Full code here
UPDATE 1
A slightly smaller implementation here using filter
Use a combination of Array.prototype.filter and Array.prototype.includes:
const filteredArray = array1.filter(value => array2.includes(value));
For older browsers, with Array.prototype.indexOf and without an arrow function:
var filteredArray = array1.filter(function(n) {
return array2.indexOf(n) !== -1;
});
NB! Both .includes and .indexOf internally compares elements in the array by using ===, so if the array contains objects it will only compare object references (not their content). If you want to specify your own comparison logic, use Array.prototype.some instead.
Destructive seems simplest, especially if we can assume the input is sorted:
/* destructively finds the intersection of
* two arrays in a simple fashion.
*
* PARAMS
* a - first array, must already be sorted
* b - second array, must already be sorted
*
* NOTES
* State of input arrays is undefined when
* the function returns. They should be
* (prolly) be dumped.
*
* Should have O(n) operations, where n is
* n = MIN(a.length, b.length)
*/
function intersection_destructive(a, b)
{
var result = [];
while( a.length > 0 && b.length > 0 )
{
if (a[0] < b[0] ){ a.shift(); }
else if (a[0] > b[0] ){ b.shift(); }
else /* they're equal */
{
result.push(a.shift());
b.shift();
}
}
return result;
}
Non-destructive has to be a hair more complicated, since we’ve got to track indices:
/* finds the intersection of
* two arrays in a simple fashion.
*
* 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())
*/
function intersect_safe(a, b)
{
var ai=0, bi=0;
var result = [];
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;
}
Compute intersection of two arrays in JavaScript - Stack Overflow
Multiple array intersection in javascript - Stack Overflow
javascript - Finding intersection in multiple arrays - Stack Overflow
How to calculate the intersection of multiple arrays in JavaScript
Here is an intersection function based on Array.prototype.filter
function intersect(a, b) {
var t;
if (b.length > a.length) t = b, b = a, a = t; // indexOf to loop over shorter
return a.filter(function (e) {
return b.indexOf(e) > -1;
});
}
var arr1 = ["mike", "sue", "tom", "kathy", "henry"];
arr2 = ["howey", "jim", "sue", "jennifer", "kathy", "hank", "alex"];
intersect(arr1, arr2); // ["sue", "kathy"]
You might also want to consider the following
var arr1 = ['sue', 'sue', 'kathy'],
arr2 = ['kathy', 'kathy', 'sue'];
The above would now give ["sue", "sue", "kathy"]. If you don't want duplicates you could do a further filter on this. This would also standardise results. i.e.
return a
.filter(/* .. */) // same as before
.filter(function (e, i, c) { // extra step to remove duplicates
return c.indexOf(e) === i;
});
Adding this will now return the same result as the previous arrays (["sue", "kathy"]), even though there were duplicates.
You could use Array.filter:
var result = arr1.filter(function(n) {
return arr2.indexOf(n) > -1;
});
You could get the values and take a Set and filter with Set#has.
var object = { filterA: ["1", "2", "3", "4"], filterB: ["2", "5", "6", "7"], filterN: ["2", "4", "7"] },
result = Object
.values(object)
.reduce((a, b) => b.filter(Set.prototype.has, new Set(a)));
console.log(result);
I have a simple one-liner approach:
const res = Object.values(object).reduce((a, b) => a.filter(i => b.includes(i)))
But since you want it in ES5 (ECMAScript 2009) version, that means no arrow functions, no includes(), and no usage of Set objects.
const res = Object.values(object).reduce(function (a, b) {
return a.filter(function(i) {
//return b.includes(i);
return b.indexOf(i) >= 0;
});
});
console.log(res);