如何判断数组是否包含另一个特定数组,而不仅仅是其元素?

时间:2016-02-16 06:11:25

标签: javascript arrays

我将直接对此进行编码,因为它非常具体。如何测试arr是否包含一个本身就是特定数组的元素。为什么我不能使用数组文字作为indexOf的arg?我正在尝试查看坐标数组是否包含特定的坐标对。

var arr = [[0,0], [1,1]];
arr[0]; // [0, 0]
arr.indexOf([0, 0]); // -1
var y = arr[0];
arr.indexOf(y); // 0
var x = [0, 0];
arr.indexOf(x); // -1

6 个答案:

答案 0 :(得分:3)

正如其他人所指出的,[0, 0] !== [0, 0]。相反,使用findIndex和一个检查数组相等的函数:

var match = [0, 0];

array.findIndex(function(elt) { return arrayIsEqual(elt, match); })

现在你只需要写arrayIsEqual。有关一些想法,请参阅How to check if two arrays are equal with JavaScript?。如果您的数组总是有两个元素,那么它可能只是elt[0] === match[0] && elt[1] === match[1]

强制性免责声明:findIndex是ES6。但是,除了显然IE11之外,它几乎可以在任何你想要的地方实现。如果需要,请使用polyfill或自己编写。

答案 1 :(得分:1)

将对象传递到array#indexOf方法可能无法提供您期望的结果

  

indexOf()方法返回可在数组中找到给定元素的第一个索引,如果不存在则返回-1。

this

希望其他人可以证实这一点。

听起来像是array.prototype.some

的完美用法
function hasCoordinates(array, coords) {
    return array.some(function(element, coords) {
        return Array.isArray(element) && String(array[element]) == String(coords);
    });
}

hasCoordinates([1,3,[4,6]], [4,6])
=> should return true

我们可以使用isArray方法来确定对象是否是数组。

应该注意some功能仅在ie9及以上

中可用

要查找确切的坐标,您无法比较数组的相等性,因为它们被视为不同的对象。

实施例

[0,0] == [0,0]
=> false

我们需要先进行类型转换

String[0,0] == String[0,0]
=> true

这是因为现在数组被评估为字符串。

答案 2 :(得分:1)

我们可以使用instanceOf来检查变量或值的类型

if(value instanceOf Array)
{
 //value is of array type
}

如果你想将它与某些特定数组进行比较,请尝试使用if语句

中的代码
var is_same = (array1.length == array2.length) && array1.every(function(element, index) {
    return element === array2[index]; 
});

如果is_same为true,那么数组是相同的

答案 3 :(得分:1)

“为什么我不能使用数组文字作为indexOf的arg?”

我相信这里的问题是数组是一个对象。您无法创建新对象

var x = [0, 0];

并期望它与arr[0];匹配,因为它与内存中的对象不同。

为了证明我认为这会起作用,但我还没有测试过它:

var arr = [[0,0], [1,1]];
var x = [0, 0];
arr[0] = x;
arr.indexOf(x); // 0

答案 4 :(得分:1)

您必须使用类似的类型才能使用.indexOf()。当您使用带有对象的比较运算符(和Arrays是对象)时,JS使用引用比较(MDN Docs)。它可能不是您想要做的,但您可以使用参考,如下所示:

var a = [0, 0];
var b = [1, 1];
var c = [1, 1];
var e = c;  // e now has the same reference as c

console.log(b == c); // false - Reference comparison is used here
console.log(c == e); // true - References are the same
var d = [a, b, c];

console.log(d.indexOf(a)); // 0
console.log(d.indexOf(b)); // 1
console.log(d.indexOf(c)); // 2
console.log(d.indexOf(e)); // 2

如果您创建了两个内部具有相同值的对象,则它们仍然没有相同的引用(如上面的代码中的b和c)。正如@torazaburo所提到的,你可以使用.findIndex()函数。

您可以执行以下操作,您可以在其中传入数组进行查找,并返回一个函数,该函数在匹配每个元素时返回true。

var a = [0, 0],
  b = [0, 0],
  c = [0, 1];

var d = [a, b, c];

function equalArrays(a) {
  return function(b) {
    if (a.length != b.length)
      return false;
    for (var i = 0, len = a.length; i < len; i++) {
      if (a[i] != b[i])
        return false;
    }
    return true;
  }
}

console.log(d.findIndex(equalArrays([0, 0]))); // 0 - index of FIRST array matching [0,0]
console.log(d.findIndex(equalArrays([0, 1]))); // 2 - index of an array matching [0,1]
console.log(d.findIndex(equalArrays([1, 1]))); // -1 - No match found

答案 5 :(得分:0)

回答最后一个问题&#34;为什么我不能使用数组文字作为indexOf的arg?&#34;答案是由于indexOf的定义方式。

请参阅ECMAScript 2015 Array.prototype.indexOf规范:http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.indexof

  

indexOf使用Strict Equality Comparison算法(7.2.13)按照升序将searchElement与数组元素进行比较,如果在一个或多个索引处找到,则返回最小的索引;否则,返回-1。

重要的部分是使用的算法;严格的平等比较。换句话说,三等于。

考虑这个JS:

var a = [1, 2];
var b = a === [1, 2]; // true or false?

b的价值是多少?这是错误的。如果您想了解更多有关原因的信息,建议您阅读https://stackoverflow.com/a/14853974/1022333