36

我正在使用 JavaScript,并且想检查数组中是否存在数组。

这是我的代码以及返回值:

var myArr = [1,3];
var prizes = [[1,3],[1,4]];
prizes.indexOf(myArr);
-1

为什么?

在 jQuery 中也是一样的:

$.inArray(myArr, prizes);
-1

为什么当元素存在于数组中时返回-1?

4

11 回答 11

42

你可以用这个

 var a = [ [1,2] , [3,4] ];
 var b = [1,2];
 a = JSON.stringify(a);
 b = JSON.stringify(b);

那么你可以只做一个 indexOf() 来检查它是否存在

var c = a.indexOf(b);
if(c != -1){
    console.log('element present');
}
于 2015-10-19T09:24:01.693 回答
17

因为[1,3] !== [1,3],因为对象只有在引用同一个对象时才会相等。您需要编写自己的搜索例程:

function searchForArray(haystack, needle){
  var i, j, current;
  for(i = 0; i < haystack.length; ++i){
    if(needle.length === haystack[i].length){
      current = haystack[i];
      for(j = 0; j < needle.length && needle[j] === current[j]; ++j);
      if(j === needle.length)
        return i;
    }
  }
  return -1;
}

var arr = [[1,3],[1,2]];
var n   = [1,3];

console.log(searchForArray(arr,n)); // 0

参考

  • 使用等式运算符

    如果两个操作数都是对象,则将它们作为对象进行比较,并且仅当两个操作数都引用同一个对象时,相等性测试才为真。

于 2013-10-23T13:50:03.287 回答
11

您可以使用 迭代数组数组,Array#some然后使用单个数组检查内部数组的每个项目Array#every

var array = [1, 3],
    prizes = [[1, 3], [1, 4]],
    includes = prizes.some(a => array.every((v, i) => v === a[i]));

console.log(includes);

于 2019-02-27T09:06:45.347 回答
4

因为这两种方法在对对象进行操作时都使用引用相等。存在的数组和您正在搜索的数组可能在结构上相同,但它们是唯一的对象,因此它们不会相等。

这将给出预期的结果,即使它在实践中没有用:

var myArr = [1,3];
var prizes = [myArr,[1,4]];
prizes.indexOf(myArr);

要执行您想要的操作,您需要编写显式递归比较数组内容的代码。

于 2013-10-23T13:50:37.413 回答
1

因为 javascript 对象是按标识而不是值进行比较的。因此,如果它们不引用同一个对象,它们将返回 false。

您需要递归比较才能正常工作。

于 2013-10-23T13:50:58.857 回答
1

首先为数组定义一个比较函数

// attach the .compare method to Array's prototype to call it on any array
Array.prototype.compare = function (array) {
    // if the other array is a falsy value, return
    if (!array)
        return false;

    // compare lengths - can save a lot of time
    if (this.length != array.length)
        return false;

    for (var i = 0; i < this.length; i++) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].compare(array[i]))
                return false;
        }
        else if (this[i] != array[i]) {
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;
        }
    }
    return true;
}

第二个只是找到数组

prizes.filter(function(a){ return a.compare(myArr)})

注意:检查array.filter的浏览器兼容性

于 2013-10-23T13:57:37.923 回答
0

假设您只处理一个二维数组(您提到了一个“数组数组”,但没有比这更深的了),这个非递归代码应该可以满足您的需求。

var compare_arrays = function (array_a, array_b) {
    var rtn = true,
        i, l;
    if (array_a.length === array_b.length) {
        for (i = 0, l = array_a.length; (i < l) && rtn; i += 1) {
            rtn = array_a[i] === array_b[i];
        }
    } else {
        rtn = false;
    }
    return rtn;
},
indexOfSimilarArray = function (arrayToFind, arrayToSearch) {
    var i = arrayToSearch.length,
        chk = false;
    while (i && !chk) {
        i -= 1;
        chk = compare_arrays(arrayToFind, arrayToSearch[i]);
    }
    return i;
};

// Test
var myArr = [1,3];
var prizes = [[1,3],[1,4]];
indexOfSimilarArray(myArr, prizes);

JSFiddle:http: //jsfiddle.net/guypursey/V7XpE/。(查看控制台以查看结果。)

于 2013-10-23T14:18:22.540 回答
0

不是 js 专家,但只是想出了如何使用Array.everyandArray.some

要查找匹配的索引:

let anarr = ['a',1, 2]
let arrofarrs = [['a',1, 2], [2,3,4]]

arrofarrs.map(
  subarr => subarr.every(
    (arr_elem, ind) => arr_elem == anarr[ind]
  )
)

// output
// Array [ true, false ]

并检查true/false数组是否包含子数组只需更改mapsome

arrofarrs.some(
  subarr => subarr.every(
    (arr_elem, ind) => arr_elem == anarr[ind]
  )
)
// output
// true

ofc 仅适用于单层嵌套,但可以递归;)

于 2021-04-26T21:34:00.237 回答
0
function doesArrayOfArraysContainArray (arrayOfArrays, array){
  var aOA = arrayOfArrays.map(function(arr) {
      return arr.slice();
  });
  var a = array.slice(0);
  for(let i=0; i<aOA.length; i++){
    if(aOA[i].sort().join(',') === a.sort().join(',')){
      return true;
    }
  }
  return false;
}

值得注意:

  • aOA[i].sort().join(',') === a.sort().join(',')是检查包含以相同顺序的相同值但引用不同对象的数组的有用方法。

  • array.slice(0)创建原始二维数组的非参考副本。

  • 但是,创建 3D 数组的副本是arrayOfArrays.slice(0)行不通的;参考链仍然存在。为了创建非参考副本,该.map函数是必需的。

如果您不创建这些非引用数组副本,您真的会遇到一些难以追踪的问题。此函数应作为条件操作,而不影响传入的初始对象。

Javascript 是一位善变的情妇。

于 2016-06-25T19:42:15.903 回答
0
function checkArrayInArray(arr, farr){
    if(JSON.stringify(arr).includes(JSON.stringify(farr))) return true;
    return false;
}
于 2021-01-26T21:57:50.683 回答
0

使用 js 映射,将数组的哈希作为键,将实际数组作为值,如果您需要遍历所有数组,您可以使用 map.values()。如果您需要查看数组是否存在,只需计算散列 o(n) 并查找 o(1)。

散列函数可以像使用 '-' 连接所有元素一样简单,如果您的数组大小很大,请从该数组 ([1,2] => 12) 中创建一个数字,并使用大素数的 mod,对于碰撞链他们。

于 2021-06-28T07:39:36.313 回答