我将直接对此进行编码,因为它非常具体。如何测试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
答案 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。
希望其他人可以证实这一点。
听起来像是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。