繁体   English   中英

有没有办法检查两个数组是否具有相同的元素?

[英]Is there a way to check if two arrays have the same elements?

假设我有 2 个数组

firstArray  = [1, 2, 3, 4, 5];
secondArray = [5, 4, 3, 2, 1];

我想知道它们是否包含相同的元素,而顺序并不重要。 我知道我可以编写一个函数来对它们进行排序,然后循环遍历它们进行检查,但是是否有为此预先构建的函数? (不仅是 Vanilla JS,其他 javascript 库也可以)

使用jQuery

您可以使用jQuery比较两个数组:

// example arrays:
var firstArray  = [ 1, 2, 3, 4, 5 ];
var secondArray = [ 5, 4, 3, 2, 1 ];

// compare arrays:
var isSameSet = function( arr1, arr2 ) {
  return  $( arr1 ).not( arr2 ).length === 0 && $( arr2 ).not( arr1 ).length === 0;  
}

// get comparison result as boolean:
var result = isSameSet( firstArray, secondArray );

这是一个JsFiddle演示

看到这个问题有用的答案

在JavaScript中有一个Array.sort()方法,并且为了比较(排序)数组,我认为最好查看这个问题 ,因为它有一个非常好的答案。

特别要注意的是,将数组作为字符串进行比较(例如通过JSON.stringify )是一个非常糟糕的主意,因为像"2,3"这样的值可能会破坏这样的检查。

这是使用Vanilla JS的工作实现:

function haveMatchingElements(firstArray, secondArray) {
    var stringsInFirstArray = parse(firstArray, 'string'),
        stringsInSecondArray = parse(secondArray, 'string'),
        numbersInFirstArray = parse(firstArray, 'number'),
        numbersInSecondArray = parse(secondArray, 'number'),
        stringResults = compare(stringsInFirstArray, stringsInSecondArray),
        numberResults = compare(numbersInFirstArray, numbersInSecondArray);

    if (stringResults && numberResults) {
        return true;
    } return false;

    function parse(array, type) {
        var arr = [];
        arr = array.sort().filter(function(index) {
            if (typeof index == type)
                return index;
        });
        return arr;
    }

    function compare(firstArray, secondArray) {
        if (firstArray.length !== secondArray.length)
            return false;
        for (var i = firstArray.length; i--;) {
            if (firstArray[i] !== secondArray[i])
                return false;
        }
        return true;
    }
}

这会将数字解析为不同的数组,并分别进行检查。 由于sort函数引起的隐式类型转换,这将纠正1"1"匹配的问题为true

实现很简单:

var arr1 = ['1', 1];
var arr2 = [1, '1'];

var results = haveMatchingElements(arr1, arr2);
console.log(results); // true  

使用原生 JavaScript

支持所有现代浏览器,您可以使用Array.prototype.every()

ECMAScript 2016

 let firstArray = [1, 2, 3, 4, 5]; let secondArray = [5, 4, 3, 2, 1]; let Equals = firstArray.every((item)=>secondArray.includes(item)) alert("Equals? " + Equals)

Internet Explorer 支持

Internet Explorer 无权访问Array.prototype.includes() 如果您需要它在 Internet Explorer 中运行,您可以使用 indexOf

 let firstArray = [1, 2, 3, 4, 5]; let secondArray = [5, 4, 3, 2, 1]; let Equals = firstArray.every(function (item){return secondArray.indexOf(item) > -1}) alert("Equals? " + Equals)

这将遍历 firstArray 中的每个项目并检查该值是否包含在 secondArray 中,并且仅当函数为 Every item 返回 true 时才返回 true

请注意,给定的函数适用于这个问题,但它是非递归的,并且只适用于两个平面数组上的原始类型,如果你想比较非原始类型,你需要修改比较函数来比较你的对象结构

假设你有:

const xs = [1,2,3];
const ys = [3,2,1];

似乎有效:

xs.every(x => ys.includes(x));
//=> true

但它会给你误报:

const xs = [2,2,2];
const ys = [1,2,3];

xs.every(x => ys.includes(x));
//=> true

// But…
ys.every(y => xs.includes(y));
//=> false

另一个例子:

const xs = [2];
const ys = [1,2,3];

xs.every(x => ys.includes(x));
//=> true

// But…
ys.every(y => xs.includes(y));
//=> false

我们可以比较两个数组的大小并快速退出,但从技术上讲,这两个数组确实包含相同的元素:

const xs = [2];
const ys = [2,2,2];

ys.every(y => xs.includes(y));
//=> true

xs.every(x => ys.includes(x));
//=> true

我回答这个问题的方法是计算两个数组的值集,并确保最大集中的所有值都包含在最小集中:

const similar = (xs, ys) => {
  const xsu = [...new Set(xs).values()]; // unique values of xs
  const ysu = [...new Set(ys).values()]; // unique values of ys
  let [small, large] = xsu.length < ysu.length ? [xsu, ysu] : [ysu, xsu];
  return large.every(l => small.includes(l));
}

similar([1,2,3],[3,2,1]);
//=> true

similar([2,2,2],[3,2,1]);
//=> false

similar([2],[3,2,1]);
//=> false

similar([2],[2,2,2]);
//=> true

similar([1,2,3],[4,5,6]);
//=> false

不是在Vanila Javascript中,但在Angular中有匹配两个对象的选项。

angular.equals([1,2,3],[1,2,3])

确定两个对象或两个值是否相等。 支持值类型,正则表达式,数组和对象。

看看这对你有帮助。

 alert("Match result of [1,2,3] & [1,2,3] is "+angular.equals([1,2,3],[1,2,3])); alert("Match result of [1,4,3] & [1,2,3] is "+angular.equals([1,4,3],[1,2,3])); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 

单击“运行代码”片段。 如果这解决了您的需要请标记为答案:)

如果顺序不重要且数组是数字类型。

 var a1 = [1, 2, 3]; var a2 = [2, 1, 3]; //In case order is not important and array is of number type. alert(eval(JSON.stringify(a1).replace(/,/g, "+").replace(/\\[/g, "").replace(/\\]/g, "")) === eval(JSON.stringify(a2).replace(/,/g, "+").replace(/\\[/g, "").replace(/\\]/g, ""))); 

这是您如何验证两个数组是否在 ES6 中具有完全相同的元素和相同的顺序:

const array1 = [1, 2, 7, 9];
const array2 = [2, 1, 3]

const arraysWithSameValuesAndOrder = (array1, array2) => {
    return array1.every((item) => array1.indexOf(item) === array2.indexOf(item)) && Boolean(array1.length === array2.length)
  }

const res = arraysWithSameValuesAndOrder(array1, array2)
console.log('res', res) FALSE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM