【问题标题】:How to check if an array contains another array?如何检查一个数组是否包含另一个数组?
【发布时间】:2017-05-30 09:36:12
【问题描述】:

我需要二维数组,所以我做了一个嵌套数组,因为 JavaScript 不允许它们。

它们看起来像这样:

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

如何检查这个数组是否包含 vanilla JS 中的特定元素(即这些 [0,1] 数组之一)?

这是我尝试过的,但没有成功(一切都返回false)(编辑:我在 sn-p 中包含了答案):

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));

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

【问题讨论】:

标签: javascript arrays


【解决方案1】:

简单易行,将数组字符串化并作为字符串进行比较

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

查看一些文档here

【讨论】:

  • 谢谢。我用你的代码更新了我的 sn-p,以函数的形式。
  • 虽然这很简单,但我觉得循环遍历数组并比较每个元素更正确。它也更快:jsperf.com/comparing-arrays2
  • 我更新为在开始时只对检查项目进行一次字符串化,而且这里所有项目都是嵌套数组,将对每个项目进行递归,所有这些都应该考虑
  • 只要所有项目都是可序列化的,这可以正常工作,但不适用于一般情况。此外,您最好使用.some 而不是.find + =null。
【解决方案2】:

你不能那样做。例如你必须自己做一些事情.. 首先,您必须从要搜索的数组中执行一个 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;

}

【讨论】:

    【解决方案3】:

    嵌套数组本质上是一个二维数组,var x = [[1,2],[3,4]] 将是一个二维数组,因为我使用 2 个索引引用它,例如,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
    

    【讨论】:

    • 谢谢。这工作正常。我选择了另一个答案,因为它看起来更简单。我用你的回答更新了我的 sn-p。
    • 关键部分是在循环之前比较两个数组的长度,考虑check = [1,2,99]
    • 是的,我们当然可以更进一步,让它适用于任何长度的数组,我已经用另一个考虑到这一点的解决方案更新了这篇文章。
    【解决方案4】:

    这是一个ES6 解决方案:

    myArray.some(
        r => r.length == itemTrue.length &&
             r.every((value, index) => itemTrue[index] == value)
    );
    

    检查JSFiddle。

    看看arrow functions 和Array 对象的some 和every 方法。

    【讨论】:

      【解决方案5】:

      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; 
      }
      

      【讨论】:

        【解决方案6】:

        对于那些有兴趣在另一个数组中查找并返回索引号的人,这里是 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。

        【讨论】:

          猜你喜欢
          • 2023-03-24
          • 1970-01-01
          • 2015-10-28
          • 1970-01-01
          • 1970-01-01
          • 2016-05-02
          • 2011-01-16
          • 1970-01-01
          相关资源
          最近更新 更多