最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is there a way to find a matching element in two arrays? - Stack Overflow

programmeradmin2浏览0评论

I have two arrays of strings :

"bob marley", "bob dylan", "bob harris"

and

"alfred hitchcock", "matt damon", "bob marley"

How would I pare these two arrays and find that Bob Marley exists in both?

I have two arrays of strings :

"bob marley", "bob dylan", "bob harris"

and

"alfred hitchcock", "matt damon", "bob marley"

How would I pare these two arrays and find that Bob Marley exists in both?

Share Improve this question asked Mar 9, 2012 at 21:05 TripTrip 27.1k48 gold badges162 silver badges281 bronze badges 5
  • Is the matching element guaranteed to be a string? – Mike Samuel Commented Mar 9, 2012 at 21:11
  • Are you trying to retrieve all matches, or just check if a value exists in both? – vol7ron Commented Mar 9, 2012 at 21:12
  • Guarenteed to be a string, yes. – Trip Commented Mar 9, 2012 at 21:20
  • Do you want the function to return an array of the matches or a boolean indicating that they have matching elements? – Kevin Bowersox Commented Mar 9, 2012 at 21:23
  • lol funny how the "naive" solutions got upvoted while the efficient ones went to oblivion... well, I guess efficiency only matters for big datasets, so no problem with that ;) – mgibsonbr Commented Mar 9, 2012 at 21:44
Add a ment  | 

9 Answers 9

Reset to default 4

If you don't want to write the array intersection yourself you can use underscores

Taken from http://documentcloud.github./underscore/

intersection_.intersection(*arrays) Computes the list of values that are the intersection of all the arrays. Each value in the result is present in each of the arrays.

 _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
 => [1, 2]
var arr1 = ["bob marley", "bob dylan", "bob harris"];
var arr2 = ["alfred hitchcock", "matt damon", "bob marley"];

$.each(arr1, function(i, val) {
    if ($.inArray(val, arr2) !== -1) {
        console.log(val + " is in both");
    }
});​

http://jsfiddle/BvTTf/

var array1 = [];
var array2 = [];
var matched = [];

for ( var i = 0; i < array1.length; i++ ){
    var s = array[i];
    for ( var j = 0; j < array2.length; j++ ){
        if ( s == array2[j] ){
             matched.push( s );
             break;
        }
    } 
}

then matched will contain strings occurring in both arrays

notice that the parison s == array2[j] is exact (case sensitive)

What you want is called an intersection of sets (in this case arrays). There are no built-in javascript or jQuery functions to do this, but you can easily code one a number of ways. Here is one:

$(function() {
    var array1 = ["bob marley", "bob dylan", "bob harris"];
    var array2 = ["alfred hitchcock", "matt damon", "bob marley", "bob dylan"];

    var intersect = $.map(array1, function(el) {
        return $.inArray(el, array2) < 0 ? null : el;
    })
});

Demo: http://jsfiddle/jtbowden/2mxzX/

Add the strings of one array as properties in an object, then search the elements from the other:

var obj = {}
var matching = [];
$.each(array1,function(index,s) { obj[s] = true; });
$.each(array2,function(index,s) {
    if ( obj[s] )
        matching.push(s);
});

If your arrays are not very big, a naive solution (paring all elements of one array to all elements of the other) might also work just fine.

You can do

function getSimilar(array1, array2) {

 var exists = {};
 var similar = [];

   for(var i = 0; i < array1.length; i++) {
     exists[array1[i]] = true;
    }
    for(var i = 0; i < array2.length; i++) {
     if(exists[array2[i]]) {
       similar.push(array2[i]);
     }
   }
  return similar;
 }
var arr = ["bob marley", "bob dylan", "bob harris"];
var arr1 = ["alfred hitchcock", "matt damon", "bob marley"];

function findCommonElements(arr, arr1){
   var matches=[];
   for(var i=0; i < arr.length;i++){
      for(var x=0; x < arr1.length; x++){
         if(arr[i] == arr1[x]){
             matches.push(arr[i]);
         }
       }
   }
  return matches;
 }

check out a working example: http://jsfiddle/Vuryj/

This is basically set intersection where sets are represented using unordered arrays. If there is an ordering function cmp that orders the elements in the arrays, then you can convert the unordered representation to an ordered representation which is easier to intersect.

function monElements(arr1, arr2, cmp) {
  // Defensively copy the input.
  arr1 = arr1.slice(0);
  arr2 = arr2.slice(0);
  // Assume the natural ordering if none is provided.
  // cmp should return a negative number to indicate that the first
  // argument is less than the second, a positive to indicate the opposite
  // and 0 to indicate equivalence.
  cmp = cmp || function (a, b) { return a < b ? -1 : a > b ? 1 : 0; };
  // Convert the input arrays to ordered form in O(n*log n) time so we
  // can intersect the arrays in O(n) time instead of O(n*m).
  arr1.sort(cmp);
  arr2.sort(cmp);
  var intersection = [];
  var i1 = 0, i2 = 0, n1 = arr1.length, n2 = arr2.length;
  while (i1 < n1 && i2 < n2) {
    var el1 = arr1[i1], el2 = arr2[i2];
    var delta = cmp(el1, el2);
    if (delta) {
      // If el1 < el2, increment i1 so we pare el2 with
      // the next element of arr1 on loop reentry.
      // Otherwise, increment i2 for similar reasons.
      if (delta < 0) { ++i1; } else { ++i2; }
    } else {  // Found a match.
      intersection.push(el1);
      ++i1, ++i2;
    }
  }
  // There will be no intersection in the unscanned portion of whichever
  // array we did not fully traverse so we're done.
  return intersection;
}

There are many answers here that all work. I think this is the fastest one if you are only dealing with strings though. It only does a single loop of each array, and then one loop through the results. Most of the other examples would do 100s or 1000s of loops if the arrays were more than just a few entries.

var names1 = ["john", "steve", "joe", "tom", "marco", "eric", "buddy"];
var names2 = ["joe", "marco", "buddy", "chris", "tim", "clarke", "pat"];

var intersection = function(firstArray, secondArray) {
    var matches = {}, results = [], a = firstArray, b = secondArray, i, l;

    for (i=0, l=a.length; i<l; i++) {
        matches[a[i]] = 1;
    }

    for (i=0, l=b.length; i<l; i++) {
        if (matches[b[i]]) matches[b[i]]++;
    }

    for (i in matches) {
        if (matches[i] === 2) results.push(i);
    }

    return results;
};

console.log(intersection(names1,names2));

Basically it loops through the first array and adds each entry to an object with a value of one. Then it runs through the second array and if the object already has a key for that then it increments it up by 1. It then loops through the object and pushes all of the keys with a value of 2 into a new array that it returns.

Even with 1000+ entries in each array, this would only do three total loops.

Here is a jsfiddle: http://jsfiddle/pseudosavant/5EeUZ/

发布评论

评论列表(0)

  1. 暂无评论