Reputation: 435
So I have 4 arrays in which each array contains names. The array either returns an array of name or null. the names are unique in an array but that name may appear in different arrays. Some arrays may be null. An example:
E.g.
Array 1 = [Bob, Sam, Mary, Jake]
;
Array 2 = [Sam, Jacob, Tom]
;
Array 3 = null
; Array 4= [Stephanie, Sam]
etc
What I want to do is to get all the strings that are common in ALL the arrays. This is what I'm thinking of: check if the arrays is null and then put the arrays that are not null in an array called, 'notNull'. And then loop through each individual element (which are an array) in notNull and then store the names that are common in the array in a variable. So in this current example, Sam should be printed out.
Upvotes: 2
Views: 477
Reputation: 13231
This code will ignore null arrays and return all matching items:
var array1 = ["Bob", "Sam", "Mary", "Jake"];
var array2 = ["Sam", "Jacob", "Tom"];
var array3 = null;
var array4 = ["Stephanie", "Sam"]
var commonNames = getCommonItems([array1, array2, array3, array4])
document.write(JSON.stringify(commonNames)) // example output
// Function
function getCommonItems(arraysToSearch) {
var commonItems = []
var started = false
for (var i = 0; i < arraysToSearch.length; ++i) {
if (arraysToSearch[i] == null) continue
if (started == false) {
for (var j = 0; j < arraysToSearch[i].length; ++j) {
commonItems.push(arraysToSearch[i][j])
}
started = true
} else {
for (var j = 0; j < commonItems.length; ++j) {
if (arraysToSearch[i].indexOf(commonItems[j]) == -1) {
commonItems.splice(j, 1);
if(commonItems.length == 0) return []
}
}
}
}
return commonItems
}
Upvotes: 2
Reputation: 29846
You can use array.prototype.every for checking if an item exists in all arrays:
var arr1 = ["a","b","c"];
var arr2 = ["c","d","e"];
var arr3 = ["f","g","c"];
var exists = [arr1,arr2,arr3].every(function(arr){return arr.indexOf("c") > -1}); // true
var exists2 = [arr1,arr2,arr3].every(function(arr){return arr.indexOf("a") > -1}); // false
You can use array.prototype.reduce for filtering on multiple arrays:
[arr1,arr2,arr3].reduce(function(a1,a2){
return a1.filter(function(item){ return a2.indexOf(item) > -1 })}, arr1);
Upvotes: 4
Reputation: 318372
Here's one way to do it, creating an array from the arguments, using Array.isArray
to remove null
, start with the first array, and just filter
the names in that based on wether or not .every
one of the rest of the arrays also have that name.
function common() {
var args = [].slice.call(arguments).filter(Array.isArray);
return args.shift().filter(function(name) {
return args.every(function(arr) {
return arr.indexOf(name) !== -1;
});
});
}
var commonNames = common(arr1, arr2, arr3, arr4 ....);
function common() {
var args = [].slice.call(arguments).filter(Array.isArray);
return args.shift().filter(function(name) {
return args.every(function(arr) {
return arr.indexOf(name) !== -1;
});
});
}
var arr1 = ["Bob", "Sam", "Mary", "Jake"];
var arr2 = ["Sam", "Jacob", "Tom"];
var arr3 = null;
var arr4 = ["Stephanie", "Sam"];
var result = common(arr1, arr2, arr3, arr4);
document.body.innerHTML = '<pre>' + JSON.stringify( result, null, 4 ) + '</pre>';
Upvotes: 3
Reputation: 2037
Here is how I would do this manually (no library).
Count the number of non-null arrays and that is the expected amount of times you expect to encounter each name.
Store each name in an object where the key is the name and the number of times it was encountered is the value.
Build an array with the names where their encountered count is the expected count (number of non-null arrays).
https://jsfiddle.net/quu66jp1/
// An array of your arrays
var arrays = [
["Bob", "Sam", "Mary", "Jake"],
["Sam", "Jacob", "Tom"],
null,
["Stephanie", "Sam"]
];
var names = {};
var expectedCount = 0;
var result = [];
// Build out the "names" object, will contain each name as a key and
// the number of times encountered as a value
for (var i=0, il=arrays.length; i<il; i++) {
if (arrays[i] !== null) {
expectedCount++;
for (var j=0, jl=arrays[i].length; j<jl; j++) {
if (!names[arrays[i][j]]) names[arrays[i][j]] = 0;
names[arrays[i][j]] ++;
}
}
}
// Build your result array with only the names that have been found
// the number of times as how many arrays were looped through.
for (var name in names) {
if (names[name] == expectedCount) {
result.push(name);
}
}
console.log(result);
Upvotes: 0
Reputation: 1383
Maybe you can try underscore intersection functions for array look here:
_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
// will return [1, 2]
don't forget to replace null Array to []
Remarque: it work with any javascript object (string...) too.
Upvotes: 0