patternjavascriptMinor
Find common elements in a list of arrays
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
Input Array of arrays:
Output:
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:
Some code that does the above (I'm no expert with Javascript, while the code works, there may be sub-optimal code here):
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
currentValuesobject. Initialize it to contain the values of the first list.
- Create a
commonValuesobject, leave it empty.
- For each of the arrays, except for the first:
- Iterate through the array. If
currentValuescontains the value, add it tocommonValues
- Set
currentValues = commonValues, and resetcommonValuesto be an empty object again.
- Finally, take the
currentValuesobject, 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.