Javascript 2维数组indexOf

35

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

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()对于二维数组不起作用...

12个回答

36

如果你想在复杂的数组中查找特定元素,就不能使用indexOf方法(除非你将数组序列化并将每个坐标转换为字符串)。相反,你需要使用for循环(或者while循环)来搜索这个数组中的特定元素,前提是你知道该数组的格式(在本例中是二维数组)。

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

否则,这可能已经足够满足您的需求。


OP的问题不是要返回该元素的索引吗?难道你不应该返回一个数字而不是一个布尔值吗?return true => return i - Joe Moore

7

Working js fiddle

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

比起简单的索引,这更像是一种hacky的方式,但它确实有效。

3

这只是一个有用的提示,可以帮助你解决问题。

使用 Lodash

该方法可获取二维数组中某个值的位置。

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

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


我更喜欢将 return el[0] == 'cow' 替换为 return el.includes('cow') - Alex Montoya
我复制粘贴并尝试了 let b = _.findIndex(a, function(el) { return el[0] == 'cow'; });,但是出现了 ReferenceError: _ is not defined - Apostolos
下划线符号 _ 是指 Lodash。https://lodash.com/ - Mendo
@Mendo,我该如何根据条件更改样式? - Gurupal singh

2
非常简单,不需要使用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*/


1
我想要有一个索引,所以我使用了:const find = this.pointList.findIndex(it => JSON.stringify(it) === JSON.stringify(item)); - Jop Knoppers

1

这是一个使用原型实现的解决方案,因此使用方式类似于indexOf,但适用于二维数组。以相同方式使用: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

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

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是需要返回其索引的数组。
注意:此函数仅返回array数组中第一次出现的findArray数组。


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

0

ES2020 更新

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

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' 这样的异常。

文档


0

在二维数组中查找元素索引的方法:

要从二维数组中获取元素的索引,可以循环遍历数组的第一层,并在第二层使用indexOf()。我创建了一个类似于indexOf的Array原型,但适用于二维数组且没有第二个参数(IndexOf(_, fromIndex)):

Array.prototype.twoDIndexOf = function(element){
  if (this === null || this === undefined)
    throw TypeError("Array.prototype.indexOf called on null or undefined")
  for(let i = 0; i < this.length; i++){
    const curr = this[i]
    if(curr.includes(element))
      return [i, curr.indexOf(element)];
  }
  return -1;
}


const exArray =  [
  ['1', '2', '3'],
  ['4', '5', '6'],
  ['7', '8', '9'],
  ['', '0', ''],
]

console.log(exArray.twoDIndexOf('7')); // [2, 0]
console.log(exArray.twoDIndexOf('6')); // [1, 2]
console.log(exArray.twoDIndexOf('')); // [3, 0]
console.log(exArray.twoDIndexOf('x')); // -1

请注意,该方法返回元素的第一个索引,这意味着如果在同一数组中重复多次出现该元素,则返回的值是其第一个位置。

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