2

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.

5
  • Why should Sam be printed if array 3 doesn't contain it? Commented Dec 23, 2015 at 16:44
  • Do you mean that the program will print out common names from notNull Arrays? Commented Dec 23, 2015 at 16:47
  • @WayneOlinger forgot to say that it should be printed out since Sam is common in the notNulls array Commented Dec 23, 2015 at 16:53
  • Concatenate all arrays then count the occurrences of each element. Commented Dec 23, 2015 at 16:53
  • @TarikhChouhan maybe you can try underscore as I mentioned in an answer down ;) Commented Dec 23, 2015 at 16:54

5 Answers 5

4

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);
Sign up to request clarification or add additional context in comments.

1 Comment

it shouldn't check for a given name, it should check is any of the names, in the notNull Array is common
3

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>';

Comments

2

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
}

5 Comments

Thanks. I tried your method and it works. Solving this was too complicated for me. You must be pretty good . Could you explain for the JSON.stringfy does?
I'm glad it helped you! JSON.stringfy converts an JavaScript-Object to a String, so you can read it in the example output.
Btw. performance-wise this should be prettymuch the best you can get
oh I see. Did you think of that on the spot or did you know who to do this through your coding experience? I'm truly astonished solved this. I've been trying to solve this for over 15 hours! I usually consult StackOverFlow at the last resort as I want to try and solve it myself
Well I saw the Question and I could imagine about how it could be done. Then I started coding, and made it on the fly. It took about 15 Minutes. Its mostly through coding experience.Trying to solve problems will take you there, your on the good way!
0

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.

Comments

0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.