4

I would like to know how to compare two or more -- potentially unlimited -- arrays for common values and push these values into a new array efficiently. Below I have a function that will accept unlimited arguments, but I am uncertain if this is a good place to begin. PHP appears to have a method that can do what I want called array_intersect. Does javascript offer something similar?

Note: I have found examples of how this can be done with two or so arrays, but I have not found examples of how such approaches might be applied to an unspecified number of arrays as of yet. Therefore I do not see this as a duplicate question.

To further clarify, the arrays might be filled with anything. Letters, numbers, symbols, words, you name it, it might be there.

var sampleOne = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var sampleTwo = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];

function FindDirectRelation() {
    for(var i = 0; i < arguments.length; ++i) {
        console.log(arguments[i]);
        

    };
};

var directRelation = FindDirectRelation(sampleOne, sampleTwo);

I am still a coding novice, so please ensure that everything is explained in a way that is simple enough for me to understand.

8
  • "potentially unlimited -- arrays " ? What is expected result of comparison ? Commented Dec 21, 2015 at 6:02
  • 1
    I have to say, if all new member questions could be this well-written our job would be much simpler :) Commented Dec 21, 2015 at 6:04
  • Interestingly enough, a search should have revealed the link posted by @DanDavis Commented Dec 21, 2015 at 6:07
  • @guest271314 I am trying to design a basic learning algorithm, and I need this function for it to find direct relations between two or more data sets. I might give it ten data sets or just two. Commented Dec 21, 2015 at 6:10
  • @dandavis I really do not know how to incorporate it. The example that you linked is a little bit over my head, but I will continue to try to understand it. Commented Dec 21, 2015 at 6:12

3 Answers 3

5

using an existing intersect that works with 2 arrays, we can chain together a common sub-set using the built-in reduce() method on an array of arrays that need intersected:

function intersect(a, b) {
  var aa = {};
  a.forEach(function(v) { aa[v]=1; });
  return b.filter(function(v) { return v in aa; });
}

var r1=[1,2,3], 
r2=[1,3,4,5], 
r3=[5,1,3];

alert([r1, r2, r3].reduce(intersect)) // shows: 1,3

if you define "intersect" as just being in more than one array (not every), then it's more complex...

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

7 Comments

Yes, I mean an intersect found in every array. Yet that has got me thinking of the benefits of identifying less frequent intersections. Give me a chance to grasp this...
keep in mind that you can pass more than 3 arrays in this manner. for perf, you can put the most different arrays (often smallest and longest) up front, if that's possible (the result is the same no matter order). Also, that intersect function is for strings/numbers, but any working intersect(a,b) function can be swapped in as needed.
I am not entirely sure yet how this works, but it does! It works with letters / strings too. Now I just need to wrap my head around this... Thanks a tonne!
the way that intersect function works is to use an object to store the values as keys. this lets us quickly ask if an object already has a value much faster than indexOf()-based solutions (a property lookup vs a sub-iteration). the reduce part is more complicated, and you should look that up instead of having me try to explain it, but it basically runs left to right treating the result of the last run as one of the 2 args of the current run, the element to the right being the other....
This should not be the accepted answer, because intersect([1],["1"]) yields ["1"]. It also does not work for elements which are not valid keys, such as objects or functions, if that is an issue.
|
0

Check to make sure the elements in the first array are also in the remaining arrays:

function multi_intersect(a) {
  var other_arrays = Array.prototype.slice.call(arguments, 1);

  return a . filter(function(elt) {
    return other_arrays.every(function(an) {
      return an.indexOf(elt) !== -1;
    });
  });
}

Comments

-1

Try using Array.prototype.filter() , Array.prototype.indexOf()

var res = sampleOne.filter(function(val) {return sampleTwo.indexOf(val) !== -1})

var sampleOne = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var sampleTwo = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
var arr = ["a", "b", "c"];
var arr1 = ["c", "d", "e"];
var arr2 = [2, 7];

function samples() {
  var args = Array.prototype.slice.call(arguments);
  var res = [];
  for (var i = 0, curr, next; i < args.length; i++) {
    if (args[i + 1]) {
      // set `curr` to array `i`
      curr = args[i];
      // set `next` to array `i + 1` if it exists
      next = args[i + 1]
    } else {
      // if at last index, set `curr` to `args` : input arrays 
      // flattened to single array , with element at `i` removed
      curr = [].concat.apply([], args.slice(0, args.length - 1));
      console.log(curr)
      // set next to current index
      next = args[i];
    };
    next = next.filter(function(val) {
      return curr.indexOf(val) !== -1 
             // filter duplicate entries at `res`
             && res.indexOf(val) === -1
    });
    res = res.concat.apply(res, next);
  };
  return res
}
var sample = samples(sampleOne, sampleTwo, arr, arr1, arr2);
console.log(sample); // [5, 6, 7, 8, 9, 10, 11, 12, "c", 2]

3 Comments

How does this deal with multiple input arrays?
I think, but am not sure, that he wants values in all the input arrays.
@torazaburo "I think, but am not sure, that he wants values in all the input arrays." Yes, js at post should filter results from all input arrays

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.