HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Find common elements in a list of arrays

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
arrayselementsfindlistcommon

Problem

I need to find the common elements present in all the given arrays. All the arrays are present in another array.

I have come up with this solution and it's working. I tried to remove the usage of indexOf, but I could not. Could someone help me optimize this?

var findCommonElements= function(arrs) {
    var resArr = [];
    for (var i = arrs[0].length - 1; i > 0; i--) {

        for (var j = arrs.length - 1; j > 0; j--) {
            if (arrs[j].indexOf(arrs[0][i]) == -1) {
                break;
            }
        }

        if (j === 0) {
            resArr.push(arrs[0][i]);
        }

    }
    return resArr;
}


Input Array of arrays:

var arrays  = [
    [1, 4, 6, 78, 8, 9, 124, 44],
    [44, 6, 9],
    [124, 44, 16, 9]
]


Output:

findCommonElements( arrays )
[44, 9]

Solution

In your code, you are using arrays to check whether the value is stored. As you have noted, that operation is \$O(n)\$. The solution to this is to use objects to check instead. That operation is \$O(1)\$, meaning that the algorithm goes from \$O(n^2)\$ to \$O(n)\$.

However, there is a problem with storing using objects, namely that all keys need to be strings. Because of this, we have to convert the strings back into integers after we are done.

Hence, our steps become:

  • Create a currentValues object. Initialize it to contain the values of the first list.



  • Create a commonValues object, leave it empty.



  • For each of the arrays, except for the first:



  • Iterate through the array. If currentValues contains the value, add it to commonValues



  • Set currentValues = commonValues, and reset commonValues to be an empty object again.



  • Finally, take the currentValues object, and convert its keys back into integers.



Some code that does the above (I'm no expert with Javascript, while the code works, there may be sub-optimal code here):

var arrays  = [
    [1, 4, 6, 78, 8, 9, 124, 44],
    [44, 6, 9],
    [124, 44, 16, 9]
];
function getCommonElements(arrays){//Assumes that we are dealing with an array of arrays of integers
  var currentValues = {};
  var commonValues = {};
  for (var i = arrays[0].length-1; i >=0; i--){//Iterating backwards for efficiency
    currentValues[arrays[0][i]] = 1; //Doesn't really matter what we set it to
  }
  for (var i = arrays.length-1; i>0; i--){
    var currentArray = arrays[i];
    for (var j = currentArray.length-1; j >=0; j--){
      if (currentArray[j] in currentValues){
        commonValues[currentArray[j]] = 1; //Once again, the `1` doesn't matter
      }
    }
    currentValues = commonValues;
    commonValues = {};
  }
  return Object.keys(currentValues).map(function(value){
    return parseInt(value);
  });
}
console.log(getCommonElements(arrays)); //Prints [9,44]

Code Snippets

var arrays  = [
    [1, 4, 6, 78, 8, 9, 124, 44],
    [44, 6, 9],
    [124, 44, 16, 9]
];
function getCommonElements(arrays){//Assumes that we are dealing with an array of arrays of integers
  var currentValues = {};
  var commonValues = {};
  for (var i = arrays[0].length-1; i >=0; i--){//Iterating backwards for efficiency
    currentValues[arrays[0][i]] = 1; //Doesn't really matter what we set it to
  }
  for (var i = arrays.length-1; i>0; i--){
    var currentArray = arrays[i];
    for (var j = currentArray.length-1; j >=0; j--){
      if (currentArray[j] in currentValues){
        commonValues[currentArray[j]] = 1; //Once again, the `1` doesn't matter
      }
    }
    currentValues = commonValues;
    commonValues = {};
  }
  return Object.keys(currentValues).map(function(value){
    return parseInt(value);
  });
}
console.log(getCommonElements(arrays)); //Prints [9,44]

Context

StackExchange Code Review Q#96096, answer score: 8

Revisions (0)

No revisions yet.