использование Array.prototype.map для вставки объекта с индексом в 2D массив

#javascript #arrays #dictionary #functional-programming

Вопрос:

Для контекста, это для классической игры в линкоры.

У меня есть массив сетки игровой доски, такой:

 [[null, null, null, null, null],
[null, null, null, null, null],
[null, null, null, null, null],
[null, null, null, null, null],
[null, null, null, null, null]],
 

Я пытаюсь поместить ship объект в массив. Объект состоит из некоторых свойств, таких как корабль name , это length и это index (так что положение, в которое попал корабль, может быть отмечено на объекте корабля). Например, корабль, помещенный в первый ряд, может выглядеть так:

[null, {name: 'boat' , index: 0 }, {name: 'boat' , index: 1 }, null, null]

Я хочу добиться этого, используя принципы функционального программирования, и избежать изменения массива, что я сейчас и делаю (т. Е. Использую для циклов и настроек array[x][y] = {ship} ).

Я понимаю, что лучший способ достичь этого-использовать map() .

Поскольку массив 2-мерный, я вкладываю две карты вместе. Моя функция до сих пор выглядит так:

 const placeShip = (ship, x, y) => {
    if (grid[x][y] !== null) return;
    const newGrid = grid.map((row, indexX) => row.map((element, indexY) => {
      if (indexX === x amp;amp; indexY === y) {
        {
          name: ship.name,
          index: XXX
        } // how to insert the index position?
      }
    }
    return newGrid
  }

 

Проблема, которую я испытываю, двояка. Во-первых, я не могу понять, как я могу правильно вставить положение индекса корабля в объект, используя вложенную карту. Это было достаточно просто, используя for циклы, когда они начинаются 0 и заканчиваются ship.length .

Во-вторых, я где-то ошибаюсь, и моя функция не возвращает 2d-массив с какими-либо объектами в нем, я просто получаю undefined .

Где я ошибаюсь?

Спасибо

Комментарии:

1. return Вот и все.

2. Не могли бы вы поподробнее, пожалуйста? Мне кажется, я слишком долго на это смотрел

3. Когда вы говорите how to insert the index position? , что неясно, какой индекс вы имеете в виду. Какой должна быть эта ценность? Один-единственный номер? массив с координатами x, y?

4. @LearningPython вы ничего не возвращаете со своей внутренней карты row .map, поэтому в итоге вы получите сетку из undefined s. Что также приведет к тому, что ваша условная проверка в начале будет иметь ложные срабатывания при последующих вызовах.

5. @Mark Я пытаюсь включить положение индекса длины судна. Возможно, это было неясно в примере, который я привожу в начале своего вопроса. В принципе, когда попадание помещается в сетку и попадает в корабль, мне нужно записать на объекте корабля, в какое положение был поражен корабль. Например, если он был длиной 4 клетки, был ли он поражен в 1-й, 2-й, 3-й или 4-й части его длины. Имеет ли это смысл?

Ответ №1:

Если вы рассматриваете только горизонтально расположенные корабли, вы можете проверить, отображается ли корабль на плитке следующим образом:

 ri === r amp;amp;    // The ship sails on the current row
ci >= c amp;amp;     // The start of the ship lies left of this column
ci < c   size  // The end of the ship lies right of this column
 

Затем индекс между 0 и shipSize может быть рассчитан с использованием: ci - c

Вот упрощенный пример:

 const grid = Array.from(Array(4), () => Array(4).fill("~~"));

const placeShipH = (r, c, size, name, grid) => grid.map(
  (row, ri) => row.map(
    (col, ci) => ri === r amp;amp; ci >= c amp;amp; ci < c   size
      ? `${name}${ci - c   1}`
      : col
  )
);

const placeShipV = (r, c, size, name, grid) => grid.map(
  (row, ri) => row.map(
    (col, ci) => ci === c amp;amp; ri >= r amp;amp; ri < r   size
      ? `${name}${ri - r   1}`
      : col
  )
);

const gridToString = grid => grid.map(row => row.join(" ")).join("n");

const afterShipA = placeShipH(1, 1, 2, "A", grid);
const afterShipB = placeShipH(3, 0, 3, "B", afterShipA);
const afterShipC = placeShipV(0, 3, 3, "C", afterShipB)

console.log(gridToString(afterShipC)); 

Комментарии:

1. Спасибо, это именно то, что я искал. Я также собираюсь адаптировать его для вертикальных компоновок, что, как я полагаю, не должно быть слишком сложно.

2. Думаю, я заговорил слишком рано. Есть ли какие-либо существенные изменения в вышеизложенном для реализации вертикального размещения? Я использую (columnIndex === column amp;amp; rowIndex >= row amp;amp; rowIndex < row ship.length) , однако мне кажется, что я получаю бесконечно длинные колонные корабли.

3. Код, который вы показали, мне нравится… Я добавил вертикальный пример в приведенном выше примере, и, похоже, он работает. Может .length быть, свойство не определено?