Check whether an array exists in an array of array

2020-01-24 09:56发布

I'm using JavaScript, and would like to check whether an array exists in an array of arrays.

Here is my code, along with the return values:

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

Why?

It's the same in jQuery:

$.inArray(myArr, prizes);
-1

Why is this returning -1 when the element is present in the array?

标签: javascript
8条回答
你好瞎i
2楼-- · 2020-01-24 09:59
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;
}

Worth noting:

  • aOA[i].sort().join(',') === a.sort().join(',') is a useful way to check for arrays that contain the same values in the same order, but are references to different objects.

  • array.slice(0) creates a non-referential copy of the original 2D array.

  • However, to create a copy of a 3D array arrayOfArrays.slice(0) does not work; the reference chain will still be present. In order to create a non-referential copy the .map function is necessary.

If you don't create these non-referential array copies you can really run into some tough to track down issues. This function should operate as a conditional and not effect the initial objects passed in.

Javascript is one fickle mistress.

查看更多
▲ chillily
3楼-- · 2020-01-24 10:00

first define a compare function for arrays

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

second just find the array with

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

NOTE: check the browser compatibility for array.filter

查看更多
不美不萌又怎样
4楼-- · 2020-01-24 10:03

You could iterate the array of arrays with Array#some and then check every item of the inner array with the single array with 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);

查看更多
ら.Afraid
5楼-- · 2020-01-24 10:05

You can use this

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

then you can do just an indexOf() to check if it is present

var c = a.indexOf(b);
if(c != -1){
    console.log('element present');
}
查看更多
forever°为你锁心
6楼-- · 2020-01-24 10:12

Assuming you are only dealing with a two-dimensional array (you mention an "array of arrays" but nothing deeper than that), this non-recursive code should do what you need.

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/. (View the console to see the result.)

查看更多
放荡不羁爱自由
7楼-- · 2020-01-24 10:21

Because [1,3] !== [1,3], since objects will only equal if they reference the same object. You need to write your own search routine:

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

References

  • Using the Equality Operators:

    If both operands are objects, they're compared as objects, and the equality test is true only if both refer the same object.

查看更多
登录 后发表回答