如何在两个数组中找到匹配的值?

IT技术 javascript arrays
2021-01-24 13:00:32

我有两个数组,我希望能够比较两者并只返回匹配的值。例如,两个数组都具有值,cat因此将返回该值我没有找到这样的东西。返回相似性的最佳方法是什么?

var array1 = ["cat", "sum","fun", "run"];
var array2 = ["bat", "cat","dog","sun", "hut", "gut"];

//if value in array1 is equal to value in array2 then return match: cat
6个回答

您可以使用 :

const intersection = array1.filter(element => array2.includes(element));
这看起来是最简单、最简洁的答案。不知道为什么它没有被标记为正确的。
2021-03-22 13:00:32
截至 2019 年 4 月下旬,只有 IE 不提供支持。
2021-03-23 13:00:32
const intersection = array1.filter(element => array2.indexOf(element) !== -1); 没有polyfill。
2021-03-31 13:00:32
@Learner 来自 ES6,您可以使用 Set 过滤掉重复的值并将其值分布在一个数组中,如下所示: const intersection = [...new Set(array1.filter(element => array2.includes(element)))];
2021-04-09 13:00:32
那是因为并非所有浏览器都支持它,除非您使用 polyfill:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-04-10 13:00:32

当然,我的方法是遍历第一个数组一次并检查第二个数组中每个值的索引。如果索引为> -1,则将push其添加到返回的数组中。

​Array.prototype.diff = function(arr2) {
    var ret = [];
    for(var i in this) {   
        if(arr2.indexOf(this[i]) > -1){
            ret.push(this[i]);
        }
    }
    return ret;
};

我的解决方案不像其他人那样使用两个循环,所以它可能运行得更快一些。如果您想避免使用for..in,您可以先对两个数组进行排序以重新索引它们的所有值:

Array.prototype.diff = function(arr2) {
    var ret = [];
    this.sort();
    arr2.sort();
    for(var i = 0; i < this.length; i += 1) {
        if(arr2.indexOf(this[i]) > -1){
            ret.push(this[i]);
        }
    }
    return ret;
};

用法如下:

var array1 = ["cat", "sum","fun", "run", "hut"];
var array2 = ["bat", "cat","dog","sun", "hut", "gut"];

console.log(array1.diff(array2));

如果您在扩展 Array 原型时遇到问题,可以轻松地将其更改为函数。

var diff = function(arr, arr2) {

并且其中FUNC原本说你随时随地更改thisarr2

indexOf() 是否足够智能以在排序后使用二分搜索?否则,这是 O(N^2) ,因为由于 indexOf() 执行线性扫描,您实际上是在进行嵌套循环。即使没有这个问题,当您可以使用对象作为哈希表在线性时间内执行此操作时,为什么会产生排序的线性成本?
2021-03-26 13:00:32
我还没有听说过任何 ECMASCript 引擎可以在排序数组上切换到二进制搜索。将是一个有趣的优化,包括在数组中携带一个“已排序”标志,但我想知道是否有足够的调用。
2021-03-27 13:00:32
.indexOf()只是移动循环。该方法在内部循环遍历目标数组。developer.mozilla.org/en-US/docs/JavaScript/Reference/...
2021-03-28 13:00:32
.indexOf()函数可能比在兼容性替代方案中循环遍历所有数组更快。
2021-04-02 13:00:32
这有点晚了,但看起来最新的 Chrome 版本至少有更快的 indexOf:jsperf.com/jquery-inarray-vs-underscore-indexof/43
2021-04-09 13:00:32

我发现@jota3 建议的内容略有改动,对我来说非常有效。

var intersections = array1.filter(e => array2.indexOf(e) !== -1);

希望这可以帮助!

这意味着您使用的是 ES2016 之前的 javascript 版本,其中添加了 includes() 。indexOf() 将适用于任何版本。
2021-03-15 13:00:32

O(n log(n) + m log(m))O(n*m)(如在其他带有 loops/ 的解决方案中所见)相比,此函数运行,这在indexOf您处理大量值时非常有用。

但是,因为既不是"a" > 1也不是"a" < 1,这仅适用于相同类型的元素。

function intersect_arrays(a, b) {
    var sorted_a = a.concat().sort();
    var sorted_b = b.concat().sort();
    var common = [];
    var a_i = 0;
    var b_i = 0;

    while (a_i < a.length
           && b_i < b.length)
    {
        if (sorted_a[a_i] === sorted_b[b_i]) {
            common.push(sorted_a[a_i]);
            a_i++;
            b_i++;
        }
        else if(sorted_a[a_i] < sorted_b[b_i]) {
            a_i++;
        }
        else {
            b_i++;
        }
    }
    return common;
}

例子:

var array1 = ["cat", "sum", "fun", "hut"], //modified for additional match
    array2 = ["bat", "cat", "dog", "sun", "hut", "gut"];
intersect_arrays(array1, array2);
>> ["cat", "hut"]
@Parthan被更快的增长所包含n logn,这同样适用于mm log n
2021-04-02 13:00:32
复杂度实际上是O(nlogn + mlogm + n + m),你在计算的时候忘记考虑while循环了。
2021-04-04 13:00:32

每次迭代第一个数组中的元素时循环遍历第二个数组,然后检查匹配项。

var array1 = ["cat", "sum", "fun", "run"],
    array2 = ["bat", "cat", "dog", "sun", "hut", "gut"];

function getMatch(a, b) {
    var matches = [];

    for ( var i = 0; i < a.length; i++ ) {
        for ( var e = 0; e < b.length; e++ ) {
            if ( a[i] === b[e] ) matches.push( a[i] );
        }
    }
    return matches;
}

getMatch(array1, array2); // ["cat"]
oop。感谢您指出了这一点 :)
2021-03-30 13:00:32
这使用数组 1 的长度 * 数组 2 的长度循环量......在这种情况下为 24 个循环。
2021-04-04 13:00:32
没问题。它有效,但它是非常不必要的,并且可能需要永远运行。您可以查看我的答案以获得更好的 1 循环解决方案
2021-04-05 13:00:32