IndexOf не работает с двумя массивами объектов - PullRequest
0 голосов
/ 22 мая 2019

Сравнивая два массива с одинаковыми номерами, IndexOf возвращает false.

Он также не работает для отдельных чисел, например, позиция [i] .location [j].Я хотел бы сравнить весь массив, а не только отдельные целые.[32, 33, 34] & [35, 34, 33] также должны возвращать true ... Есть ли лучший способ?

(...)
//Array of ship locations
ships: [
        {location:[13, 23, 33]},
        {location:[2, 12, 22]},
        {location:[15, 14, 16]},
        {location:[17, 18, 19]},
        {location:[31, 41, 51]},
        {location:[40, 41, 42]}
    ],
//Array with additional ship location
position: [
        {location: [2, 12, 22]},
        {location: [40, 41, 42]}
    ],    


collision: function(position) {

     if(this.ships.length > 1) {

            for(var i = 0; i < this.ships.length; i++) {
                for(var j = 0; j < position.length; j++) {


            if(this.ships[i].location.indexOf(this.position[j].location) >= 0) {
                        return true;
                           } else {
                            return false;
                               }
                }

            }

      } else {
          return false;
      }


}

console.log(model.collision(model.position)); //returns false

Ответы [ 3 ]

1 голос
/ 22 мая 2019

Чтобы найти коллизию в вашем сценарии, вам нужно выполнить итерацию по первому набору, и для каждого массива проверить, присутствуют ли какие-либо / некоторые элементы в другом наборе массивов.Вот код, который делает это:

let ships = [ {location:[13, 23, 33]}, {location:[2, 12, 22]}, {location:[15, 14, 16]}, {location:[17, 18, 19]}, {location:[31, 41, 51]}, {location:[40, 41, 42]} ]
let position = [{location: [22, 12, 22]},{location: [40, 41, 42]}]

// Compares if two arrays of numbers in this case are equal by making sure values 
// at array indexes are equal
let isSameArray = (a,b) => a.every((number, index) => b[index] === number)

// Compares the sets by iterating over each of the elements inside and 
// calling `isSameArray`
let contains = (a,b) => a.some(x => b.some(y => isSameArray(x.location, y.location)))

console.log(contains(ships, position)) // true
console.log(contains([{location:[22, 12, 22]}],[{location:[2, 12, 22]}])) // false

это в ES5 будет выглядеть так:

let ships = [ {location:[13, 23, 33]}, {location:[2, 12, 22]}, {location:[15, 14, 16]}, {location:[17, 18, 19]}, {location:[31, 41, 51]}, {location:[40, 41, 42]} ]
let position = [{location: [22, 12, 22]},{location: [40, 41, 42]}]

let isSameArray = function(arr1, arr2){
  return arr1.every(function(number, index){
    return arr2[index] === number
  })
}

let contains = function(setA, setB){
  return setA.some(function(objA) {
    return setB.some(function(objB) {
      return isSameArray(objA.location, objB.location)
    })
  })
}

console.log(contains(ships, position))  // true
console.log(contains([{location:[22, 12, 22]}],[{location:[2, 12, 22]}]))  // false

Теперь этот код использует Array.some и Array.every , которые оба возвращают логическое значение в первом случае, указывая, что all элементы соответствуют функции предиката, а во втором - хотя бы одно совпадение.

Вы также можете сделать это с вашим подходом, если вы включите фактическую функцию для сравнения числовых массивов location:

let ships = [ {location:[13, 23, 33]}, {location:[2, 12, 22]}, {location:[15, 14, 16]}, {location:[17, 18, 19]}, {location:[31, 41, 51]}, {location:[40, 41, 42]} ]
let position = [{location: [22, 12, 22]},{location: [40, 41, 42]}]

let isSameArray = function(arr1, arr2){
  return arr1.every(function(number, index){
    return arr2[index] === number
  })
}

let collision = function(arr1, arr2) {
  for(var i = 0; i < arr1.length; i++) {
    for(var j = 0; j < arr2.length; j++) {
      if(isSameArray(arr1[i].location, arr2[j].location))
	return true
    }
  }
  return false
} 

console.log(collision(ships, position))   // true
1 голос
/ 22 мая 2019

Метод .indexOf не будет работать со сложными объектами, такими как массивы или литералы объектов в javascript, из-за поведения, известного как «Передано по значению против Передано по ссылке».Это длинная тема, касающаяся того, как примитивные значения (строки, числа, логические значения) хранятся по сравнению с тем, как хранятся сложные значения (объекты).

Если вы хотите сравнить, являются ли два массива "одинаковыми" (то есть, если два массива содержат одинаковую последовательность целых чисел), вы должны проверить каждый индекс в каждом массиве.

0 голосов
/ 22 мая 2019

Я пытался .includes (); вместо .indexOf (); и работает нормально. Даже я не знаю почему ...

...