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

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.