Удалить данные клетки в 2D Array в JavaScript - PullRequest
0 голосов
/ 12 марта 2019

Учитывая массив и индексы ячеек, удалите все данные индексы ячеек.

Ввод:

[[0,1,2,3,4,5],
 [0,1,2,3,4,5],
 [0,1,2,3,4,5]
]

Ячейки:

(0,1) (1,1), (2,4), (0,2)

Ожидаемый результат:

[[0,3,4,5],
 [0,2,3,4,5],
 [0,1,2,3,5]
]

Когда я пытаюсь удалить исходный массив, меняется, так что я не могу удалить соответствующие индексы.Мы не должны изменять массив, пока все не будет удалено.

  obj[key].forEach(element => {
    arr[element].splice(key, 1)
  });

Ответы [ 4 ]

2 голосов
/ 12 марта 2019

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

  • Удаление ячейки в (0,1) с использованием Array.prototype.splice() изменит первую строку с [0,1,2,3,4,5] на [0,2,3,4,5]
  • Когда вы снова столкнетесь с той же строкой, напримерудаляя другую ячейку в (0,2), вы фактически удаляете 3 из первой строки, поскольку строка теперь мутировала

Чтобы избежать этого, единственный способ - заменить значения в ячейках.что вы хотите удалить в первом проходе с помощью null.Затем выполните второй проход через матрицу, чтобы удалить эти null значения:

const matrix = [
  [0,1,2,3,4,5],
  [0,1,2,3,4,5],
  [0,1,2,3,4,5]
];

const cellsToRemove = [
  [0,1],
  [1,1],
  [2,4],
  [0,2]
];

cellsToRemove.forEach(cell => {
  const x = cell[0];
  const y = cell[1];
  matrix[x][y] = null;
});

const newMatrix = matrix.map(row => {
  return row.filter(col => col !== null);
});
console.log(newMatrix);
1 голос
/ 12 марта 2019

Немного другой подход.

let cellsToRemove = [
    [1, 2], //(0,1) + (0,2)
    [1], //(1,1)
    [4], //(2,4)
];
let arr = [
    [0, 1, 2, 3, 4, 5],
    [0, 1, 2, 3, 4, 5],
    [0, 1, 2, 3, 4, 5]
];


let newArr = [];
for (i = 0; i < arr.length; i++) {
    newArr.push(arr[i].filter((item) => {
        return !cellsToRemove[i].includes(item)
    }));
}
console.log(newArr);

Я думаю, что решение Терри является лучшим.

1 голос
/ 12 марта 2019

Вы можете отсортировать индексы по второму убыванию индекса, потому что splice меняет индекс.

var array = [[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]],
    remove = [[0, 1], [1, 1], [2, 4], [0, 2]];
    
remove
    .sort((a, b) => b[1] - a[1])
    .forEach(([i, j]) => array[i].splice(j, 1));

array.map(a => console.log(...a));
1 голос
/ 12 марта 2019

Не самый эффективный, но вот быстрое и грязное решение с reduce и map:

const input = [
  [0,1,2,3,4,5],
  [0,1,2,3,4,5],
  [0,1,2,3,4,5]
];

const removals = [[0,1], [1,1], [2,4], [0,2]];
const _ = {};
const output = removals
  .reduce((a, [x, y]) => (a[x][y] = _, a), input)
  .map(r => r.filter(c => c !== _));
output.forEach(r => console.log(...r));

Я решаю проблему смещения индексов, просто помечая ячейки для удаления с помощью заполнителя (_) в одном цикле и возвращаясь в другом цикле.чтобы удалить все отмеченные ячейки.

Другое решение было бы sort индексами, которые будут удалены перед циклом их прохождения, и тогда вы можете просто splice как обычно.

const input = [
  [0,1,2,3,4,5],
  [0,1,2,3,4,5],
  [0,1,2,3,4,5]
];

const removals = [[0,1], [1,1], [2,4], [0,2]];
const output = removals
  .sort(([a, b], [c, d]) => d - b)
  .reduce((a, [x, y]) => (a[x].splice(y, 1), a), input);
output.forEach(r => console.log(...r));
...