1

What this should be able to do is take in a 2D array filled with one letter values and return an array of all the shared values. This is what I have so far:

var res = array[0].filter(function(x){
        return array.every(function(y){
             return y.indexOf(x) >= 0
        })
    });
return res;  

This is in some form of working state but only under certain condition which makes it very hit and miss. Working as intended:

var array = [["x","x"],
             ["x","x","x"]];

This returns the expected array of ["x","x"] but when like this:

var array = [["x","x","x"],
             ["x","x"]];

It returns ["x","x","x"]

As you can see the two arrays only share 2 common x's but the code doesn't reflect that in different situations. Also it should be able to handle arrays with other letters like so:

var array = [["x","x","z","y","y"],
             ["x,"x","x","y"],
             ["x","x","z","y"]];

With something like this it should return ["x","x","y"] as all arrays share 2 common x's and 1 common y

3
  • So you want a function that you can pass in an arbitrary number of arrays to, and then get back common values, regardless of index ? Commented Dec 28, 2015 at 16:27
  • 1
    There is no y in the 3rd array. Commented Dec 28, 2015 at 16:28
  • Yes, I didn't make that clear with how I set up the examples but yes Commented Dec 28, 2015 at 16:29

3 Answers 3

3

Use a combination of .every and .filter, use .indexOf to check whether a element exists in an array or not.

var array = [
  ["x", "x", "z", "y", "y"],
  ["x", "x", "x", "y"],
  ["x", "x", "z", "y"]
];

var res = array[0].filter(function(x) {
  return array.every(function(y) {
    if (y.indexOf(x) != -1) {
      y[y.indexOf(x)] = Infinity;
      return true;
    }
    return false;
  })
})

alert(res)

Sign up to request clarification or add additional context in comments.

Comments

0

Here's another way, using Array methods only availble from IE9 etc.

function compareValues() {
    var arrs = [].slice.call(arguments).sort(function(a,b) {
    	return a.length > b.length; // always iterate shortest array
    });
    
    return arrs.shift().filter(function(x, i) { // filter the first array
    	return arrs.every(function(arr) {       // if all other arrays
       	    return arr[i] === x;                // have the same value at the same index
        })
    });
}

var result = compareValues(["x","x","x","y"], 
                           ["x","x","z","y"], 
                           ["x","x","z","y","y"]);

alert(result);

Comments

0

This is a proposal with Array.prototype.reduce(), Array.prototype.filter() and Array.prototype.indexOf() for nondestructive search.

var array = [
        ["x", "x", "z", "y", "y"],
        ["x", "x", "x", "y"],
        ["x", "x", "z", "y"]
    ],
    result = array.reduce(function (r, a) {
        var last = {};
        return r.filter(function (b) {
            var p = a.indexOf(b, last[b] || 0);
            if (~p) {
                last[b] = p + 1;
                return true;
            }
        });
    });

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.