如何检查一个数组是否包含另一个数组?

13

因为 JavaScript 不允许二维数组,所以我创建了一个嵌套数组。

它们长成这个样子:

var myArray = [
  [1, 0],
  [1, 1],
  [1, 3],
  [2, 4]
]

我该如何在原生JS中检查此数组是否包含特定元素(例如这些[0,1]数组之一)?
这是我尝试过的方式,但都没有成功(每个都返回false):(编辑:我在代码段中包含了答案)

var myArray = [
  [1, 0],
  [1, 1],
  [1, 3],
  [2, 4]
]

var itemTrue = [2, 4];
var itemFalse = [4, 4];

function contains(a, obj) {
  var i = a.length;
  while (i--) {
    if (a[i] === obj) {
      return true;
    }
  }
  return false;
}

// EDIT: first answer's solution

function isArrayInArray(x, check) {
  for (var i = 0, len = x.length; i < len; i++) {
    if (x[i][0] === check[0] && x[i][1] === check[1]) {
      return true;
    }
  }
  return false;
}

// EDIT: accepted answer's solution


function isArrayInArray2(x, check) {
  var result = x.find(function(ele) {
    return (JSON.stringify(ele) === JSON.stringify(check));
  }) 
  return result !=null
}

console.log("true :" + myArray.includes(itemTrue));
console.log("false :" + myArray.includes(itemFalse));

console.log("true :" + (myArray.indexOf(itemTrue) != -1));
console.log("false :" + (myArray.indexOf(itemFalse) != -1));

console.log("true :" + contains(myArray, itemTrue));
console.log("false :" + contains(myArray, itemFalse));

// EDIT: first answer's solution
console.log("true :" + isArrayInArray(myArray, itemTrue));
console.log("false :" + isArrayInArray(myArray, itemFalse));


// EDIT: accepted answer's solution
console.log("true :" + isArrayInArray2(myArray, itemTrue));
console.log("false :" + isArrayInArray2(myArray, itemFalse));

这可能看起来是重复的,但我找不到类似的问题。如果是,请随意标记为这样。


我看了那个问题,但它并没有解决我的问题。请查看更新的代码片段,其中包含该问题的答案2的解决方案。 - Billybobbonnet
在内部,该函数将检查 if (paramArray[i] == searchElement),但这会失败,因为您无法使用 == 比较两个数组,因此您不能使用 includes 来执行此操作。 - pushkin
请返回翻译后的文本:重复的https://dev59.com/p2015IYBdhLWcg3w6QLA - Asif Saeed
考虑到这是一个特定的情况(伪二维数组),这不是https://dev59.com/p2015IYBdhLWcg3w6QLA的重复,该问题并没有直接解决我的问题。请移除标记。 - Billybobbonnet
6个回答

13

简单明了,将数组转换为字符串并作为字符串进行比较

function isArrayInArray(arr, item){
  var item_as_string = JSON.stringify(item);

  var contains = arr.some(function(ele){
    return JSON.stringify(ele) === item_as_string;
  });
  return contains;
}

var myArray = [
  [1, 0],
  [1, 1],
  [1, 3],
  [2, 4]
]
var item = [1, 0]

console.log(isArrayInArray(myArray, item));  // Print true if found

点击此处查看相关文档。


1
谢谢。我用你的代码更新了我的片段,形式是一个函数。 - Billybobbonnet
虽然这很简单,但我觉得通过循环数组并比较每个元素更正确。而且速度更快:https://jsperf.com/comparing-arrays2 - pushkin
我更新了字符串化检查项,仅在开始时检查一次。此外,这里的所有项目都是嵌套数组,将为每个项目执行递归,所有这些都应该被考虑进去。 - mohamed-ibrahim
只要所有项目都是可序列化的,这个方法就可以正常工作,但对于一般情况则不然。此外,最好使用.some而不是.find + =null - georg
正如在这里的评论中提到的那样,当item = ['1', 0]时,这种方法是不起作用的。 - Gangula

5

嵌套数组实际上是一个二维数组,例如var x = [[1,2],[3,4]]就是一个二维数组,因为我们需要使用两个索引进行引用,例如x[0][1]将返回2

回到您的问题,您可以使用普通循环来判断它们是否已包含,因为这对于复杂数组不受支持:

var x = [[1,2],[3,4]];
var check = [1,2];
function isArrayInArray(source, search) {
    for (var i = 0, len = source.length; i < len; i++) {
        if (source[i][0] === search[0] && source[i][1] === search[1]) {
            return true;
        }
    }
    return false;
}
console.log(isArrayInArray(x, check)); // prints true

更新适用于任何长度数组的方法

function isArrayInArray(source, search) {
    var searchLen = search.length;
    for (var i = 0, len = source.length; i < len; i++) {
        // skip not same length
        if (source[i].length != searchLen) continue;
        // compare each element
        for (var j = 0; j < searchLen; j++) {
            // if a pair doesn't match skip forwards
            if (source[i][j] !== search[j]) {
                break;
            }
            return true;
        }
    }
    return false;
}
console.log(isArrayInArray([[1,2,3],[3,4,5]], [1,2,3])); // true

谢谢。这个很好用。我选择了另一个答案,因为它看起来更简单。我用你的答案更新了我的代码片段。 - Billybobbonnet
关键部分是在循环之前比较两个数组的长度,考虑 check = [1,2,99] - georg
是的,我们肯定可以进一步进行编程,并使其适用于任何长度的数组。我已经更新了帖子,并提供了另一种解决方案来考虑这一点。 - dayvidwhy

4
这里是一个ES6解决方案:
myArray.some(
    r => r.length == itemTrue.length &&
         r.every((value, index) => itemTrue[index] == value)
);

请查看JSFiddle的代码。

了解箭头函数以及Array对象的someevery方法。


3

你不能这样做。例如,你必须自己做一些事情。首先,你需要对你想要搜索的数组进行foreach循环,并为每个数组项运行“compareArray”函数。

function compareArray( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;


    for(var i=0;i<arrA.length;i++){
         if(arrA[i]!==arrB[i]) return false;
    }

    return true;

}

1
D. Young的评论提供的检查任何长度数组的代码是有缺陷的。它只检查第一个元素是否相同。
D. Young评论的修正版本:
function isArrayInArray(source, search) {
    var searchLen = search.length;
    for (var i = 0, len = source.length; i < len; i++) {
        // skip not same length
        if (source[i].length != searchLen) continue;
        // compare each element
        for (var j = 0; j < searchLen; j++) {
            // if a pair doesn't match skip forwards
            if (source[i][j] !== search[j]) {
                break;
            } else if (j == searchLen - 1) {return true}
        }
    }
    return false; 
}

0

对于那些有兴趣在一个数组中查找另一个数组并返回索引号的人,这里是mohamed-ibrahim's answer的修改版本:

function findArrayInArray(innerArray, outerArray) {
    const innerArrayString = JSON.stringify(innerArray);
    let index = 0;
    const inArray = outerArray.some(function (element) {
        index ++;
        return JSON.stringify(element) === innerArrayString;
    });
    if (inArray) {
        return index - 1;
    } else {
        return -1;
    }
}
findArrayInArray([1, 2, 3], [[3, .3], [1, 2, 3], [2]]); // 1
findArrayInArray([1, 2, 3], [[[1], 2, 3], [2]]) // -1

此函数返回你正在查找的内部数组在外部数组中的索引,如果未找到则返回-1。

请查看此CodePen


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接