Javascript 2d数组indexOf

时间:2014-07-24 20:18:40

标签: javascript arrays 2d indexof

我有一个像这样的二维数组:

var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];

每个索引都存储一个包含某个元素坐标的内部数组。

如何使用Array.indexOf()检查新生成的坐标集是否已包含在arr中?如果只有坐标不重复,我想进入arr

这是我的尝试,但没有成功:

if (arr.indexOf([x, y]) == -1) {
    arr.push([x, y]);
}

indexOf()似乎不适用于2D阵列......

10 个答案:

答案 0 :(得分:17)

你不能使用indexOf做复杂的数组(除非你序列化它使每个坐标都成为字符串),你需要使用for循环(或while)来搜索该数组中的坐标,假设你知道格式数组(在这种情况下是2d)。

var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];
var coor1 = [0, 9];
var coor2 = [1, 2];

function isItemInArray(array, item) {
    for (var i = 0; i < array.length; i++) {
        // This if statement depends on the format of your array
        if (array[i][0] == item[0] && array[i][1] == item[1]) {
            return true;   // Found it
        }
    }
    return false;   // Not found
}

// Test coor1
console.log("Is it in there? [0, 9]", isItemInArray(arr, coor1));   // True

// Test coor2
console.log("Is it in there? [1, 2]", isItemInArray(arr, coor2));   // False

// Then
if (!isItemInArray(arr, [x, y])) {
   arr.push([x, y]);
}

此实现循环并获取每个值。如果你关心性能,你可以做更复杂的事情,比如用第一个索引对原始数组进行排序,然后在第一个索引上使用二进制搜索。

另一种方法是将数组中每个项目的第一个坐标存储在一个对象(如哈希表)中,并在每个存储桶中存储第二个值以减少搜索时间;更多信息http://en.wikipedia.org/wiki/Bucket_sort

否则,这可能足以满足您的需求。

答案 1 :(得分:6)

Working js fiddle

for(var k = 0; k < arr.length; k++){
    if(arr[k][0] == x && arr[k][1] == y){
        found = true;
    }
}

更多的是一种hacky方式,而不是简单的索引,但它有效

答案 2 :(得分:2)

不是一个完整的答案只是一个可能有用的旁注。

使用Lodash

此方法将为您提供二维数组中值的位置

let a = [ [ 'bird' ], [ 'cat' ], [ 'dog' ], [ 'cow' ], [ 'bird' ] ];
let b = _.findIndex(a, function(el) { return el[0] == 'cow'; });
console.log(b);//answer is 3

如前所述,您需要一个嵌套循环来遍历数组。

答案 3 :(得分:1)

因为这是一个二维数组,所以你需要一个嵌套的for循环。

var newArr = [1, 2],
    counter;


for ( var i = 0; i < arr.length; i++ ) {

    for ( var x = 0; x = arr[i].length; x++ ) {

        if ( arr[i][x] === newArr[x] {

             counter++ 
        }

        if (counter === 2) {
            alert('new coord!')
        }
    }
    //reset counter
    counter = 0;
}

答案 4 :(得分:1)

这就是我实现的

getIndexOfArray(array: any[], findArray: any[]): number{
  let index = -1;
  array.some((item, i)=>{
    if(JSON.stringify(item) === JSON.stringify(findArray)) {
      index = i;
      return true;
    }
  });
  return index;
}

这里array是我们需要索引的数组,而findArray是将返回其索引的数组。
注意::此函数将仅返回findArray阵列见解array阵列的首次出现。

答案 5 :(得分:1)

ES2020 更新

如果您能够支持 ES2020,则可以使用新的 ?. operator(可选链运算符)。它可以用于二维数组,如下所示:

const arr = [[1,2],[3,4]];

if ( ! arr[5]?.[6] ) {
  console.log("Index out of bounds");
}

if ( arr[0]?.[0] ) {
  console.log("Index in bounds");
}

如果您尝试使用可选链运算符访问任何 undefined 的属性,它将评估为 undefined 而不是抛出类似 Cannot read property 'foo' of 'undefined' 的内容。


文档

答案 6 :(得分:0)

之前的回答说:

  

你不能使用indexOf做复杂的数组(除非你序列化它,使每个坐标成为字符串)...

以下是你如何做到的。如果你有一个非常大的数据集,我建议不要使用这种技术,因为它依赖于你的2D数组的副本。但对于合理的集合,它很简单。

使用一致的方法展平数组元素,例如:

// Flatten array into a string, separating elements with a "unique" separator.
function stringle( arr ) {
  return arr.join(' |-| ');
}

对于您的示例来说,这是过度的,其中子数组包含整数,但它占据了更复杂的数据类型。 (如果我们使用逗号,默认情况下,例如,从包含逗号的字符串元素中将无法识别。)

然后可以将目标数组展平为一个字符串数组:

// Transmogrify arr into a String[], usable with indexOf()
var arrSearch = arr.map(function(row) { return stringle(row); });

然后您可以使用Array.indexOf()(或其他数组方法)来检查匹配的存在或位置。

if (arrSearch.indexOf( stringle(newArray) ) === -1) ...

此代码段包含此演示,包含多种数据类型。

&#13;
&#13;
// Example starting array
var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];

// Flatten array into a string, separating elements with a "unique" separator.
function stringle( arr ) {
  return arr.join(' |-| ');
}

snippet.log("arr: "+JSON.stringify(arr));

// Transmogrify arr into a String[], usable with indexOf()
var arrSearch = arr.map(function(row) { return stringle(row); });

snippet.log("arrSearch: "+JSON.stringify(arrSearch));

var tests = [[0, 9],[1, 2],["pig","cow"],[0,9,"unicorn"],["pig","cow"]];

for (var test in tests) {
  var str = stringle(tests[test]);
  if (arrSearch.indexOf(str) === -1) {
    arr.push(tests[test]);
    arrSearch.push(str);
    snippet.log("Added "+JSON.stringify(tests[test]));
  }
  else {
    snippet.log("Already had "+JSON.stringify(tests[test]));
  }
}

snippet.log("Result: "+JSON.stringify(arr));
&#13;
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
&#13;
&#13;

答案 7 :(得分:0)

你可以使用这种方法,

function isArrayItemExists(array , item) {
    for ( var i = 0; i < array.length; i++ ) {
        if(JSON.stringify(array[i]) == JSON.stringify(item)){
            return true;
        }
            }
            return false;
}

答案 8 :(得分:0)

非常简单,没有indexOf ...

var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];
const isDup = (x,y) => {
   arr.find(it => JSON.stringify(it) == JSON.stringify([x,y])) == undefined ? arr.push([x,y]) : null
}

console.log(isDup(2,3)) /* Does not add */
console.log(isDup(1,2)) /*Does add*/
console.log(arr) /*Confirmation*/

答案 9 :(得分:0)

这里是使用原型完成的解决方案,因此其用法类似于indexOf,但用于2d数组。使用相同的方法: arr.indexOf2d([2,3]);

var arr = [[2,3],[5,8],[1,1],[0,9],[5,7]];

Array.prototype.indexOf2d = function(item) {
    // arrCoords is an array with previous coordinates converted to strings in format "x|y"
    arrCoords = JSON.stringify(this.map(function(a){return a[0] + "|" + a[1]}));

    // now use indexOf to find item converted to a string in format "x|y"
    return arrCoords.indexOf(item[0] + "|" + item[1]) !== -1;
}
arr.indexOf2d([2,3]); // true
arr.indexOf2d([1,1]); // true
arr.indexOf2d([6,1]); // false