dadadodo
dadadodo

Reputation: 347

compare elements of array of many arrays

I trying to loop through an array of arrays, and compare the elements with each-other in-order to find the common elements. so lets say if we have var arr = [[1,2,3],[4,2,5]]; I want to first compare [i][i] and [i+1][i], [i][i+1] and [i+1][i+1] and [i][i+2] and [i+1][i+2] and so on. here is my code:

function sym(args) {
  var fullArr = [];
  var finalArr = [];
  // store the arguments inside a single array
  for (var count = 0; count < arguments.length; count ++) {
    fullArr[count] = arguments[count];
  }
  // loop through finalArr[];
  for (var i = 0; i < fullArr.length; i++) {
    if (fullArr[i][i] == fullArr[i++][i++]) {
      // if the element matches (it is a common element)
      // store it inside finalArr
      finalArr[i] = fullArr[i];
    }
  }
  return finalArr;
}

sym([1, 2, 3], [5, 2, 1, 4]);

problem: when I run the code instead of an array containing the matching element, I get an empty array

Upvotes: 2

Views: 1597

Answers (3)

Luke Kot-Zaniewski
Luke Kot-Zaniewski

Reputation: 1161

You first have to iterate over one array and see if the other array includes the value you have specified.

My answer is similar to a nested for loop in that the includes method does exactly that. It takes in as a parameter an element and checks if the array which called it contains said element. In order to do that it must iterate through all elements in the array in the worst case.

My answer also assumes that you only want to count duplicate matches once.

function sym(args) {
  var fullArr = [];
  var finalArr = [];
  // store the arguments inside a single array
  for (var count = 0; count < arguments.length; count ++) {
    fullArr[count] = arguments[count];
  }
  // loop through finalArr[];
  
  //since you are comparing only two arrays in this 
 //example you just have to iterate over each element in the first array aka fullArr[0] and
 //check if each element "e" is also in the second array aka fullArr[1] 
 //AND that your final output array does not already contain it.
 //If both of these are true then we push the element to the output array.
  fullArr[0].forEach(function(e){
       if(fullArr[1].includes(e) && !finalArr.includes(e)) finalArr.push(e);
    
    });
  return finalArr;
}

sym([1, 2, 3], [5, 2, 1, 4]);

However if you want to check if a particular element exists in all collections of an n length array then I would propose something like this:

function sym(args) {
  var fullArr = [];
  var finalArr = [];
  // store the arguments inside a single array
  for (var count = 0; count < arguments.length; count ++) {
    fullArr[count] = arguments[count];
  }
      
      var newArr = fullArr[0].reduce( function(prev, e1) {
         if(prev.indexOf(e1) < 0 && fullArr.every( function(arr){
                   return arr.indexOf(e1) > -1;
             })){
             return [...prev, e1];    
           }else{
                   return prev;
           };
       },[]);
       alert(newArr);        
       return newArr;
}

sym([1,1, 2, 3,4], [5, 2, 1, 4], [4,1,2, 5]);

Upvotes: 1

vladzam
vladzam

Reputation: 5918

In your code, when the following line executes, you also increment the value of i which is your control variable:

if (fullArr[i][i] == fullArr[i++][i++])

Thus, this is how your i variable gets incremented in each iteration:

Iteration #1: i = 0

Iteration #2: i = 3 - you get i+2 from the line that I mentioned above, +1 more from the increment that you specify in the final condition of the for loop

Therefore, even after the first iteration, your function will return an empty array on your particular scenario, as you are passing an array of length 3, and the for loop ends after i = 0 on the first iteration.

Even if the loop would go on, it would return an index out of bounds exception because your array of length 3 would not have an array[3] element.

For example, if you want to compare just two arrays, as in your scenario, you need to loop through each of them and compare their elements:

function sym(array1, array2) {
  var results = [];


  for (var i = 0; i < array1.length; i++) {
      for (var j = 0; j < array2.length; j++) {
          if(array1[i] === array2[j]) {
              if(results.indexOf(array1[i]) === -1) {
                  results.push(array1[i]);
              }
          }
      }
  }

  return results;
}

sym([1, 2, 3], [5, 2, 1, 4]);

I have also built a solution that returns the intersection of the arrays that you provide as the parameters for the function, regardless of how many arrays there are:

function sym(args) {
    var paramSet = Array.prototype.slice.call(arguments);
    var counterObject = {};
    var results = [];

    paramSet.forEach(function (array) {
        // Filter the arrays in order to remove duplicate values
        var uniqueArray = array.filter(function (elem, index, arr) {
            return index == arr.indexOf(elem);
        });


        uniqueArray.forEach(function (element) {
            if (Object.prototype.hasOwnProperty.call(counterObject, element)) {
                counterObject[element]++;
            } else {
                counterObject[element] = 1;
            }
        });
    });


    for (var key in counterObject) {
        if (counterObject[key] === paramSet.length) {
            results.push(parseInt(key));
        }
    }

    return results;

}

sym([1, 2, 3, 3, 3], [5, 2, 1, 4], [1, 7, 9, 10]);

The above code will return [1] for the example that I provided, as that is the intersection of all 3 arrays.

Upvotes: 0

naortor
naortor

Reputation: 2087

You can iterate over the first array and check if any of its values are common through all the other arrays.

function sym() {
    var common = [];
    for (var i=0; i<arguments[0].length; i++) {
        var isCommon = common.indexOf(arguments[0][i]) === -1; // first check if its not already exists in the common array
        for (var j=1; j<arguments.length && isCommon; j++) {
            isCommon = arguments[j].indexOf(arguments[0][i]) > -1
        }
        if (isCommon) common.push(arguments[0][i])
    }
    return common;
}

of course you can improve it by iterating over the smallest array.

Upvotes: 1

Related Questions