Skip to main content

Обхід двовимірного масиву

Обхід двовимірного масиву (матриці) це одна з базових, але дуже важливих операцій. Оскільки це масив масивів, його обходять вкладеними циклами: зовнішній іде по рядках, внутрішній по стовпцях. Спосіб обходу обирають за тим, чи потрібні індекси і чи треба мати змогу перервати цикл.

Теорія

TL;DR

  • Двовимірний масив обходять вкладеними циклами: зовнішній по рядках, внутрішній по елементах рядка.
  • Класичний for дає повний контроль і доступ до індексів i та j.
  • Два вкладені for...of це найчитабельніший сучасний варіант.
  • forEach() дає індекси другим аргументом, але його не можна перервати через break.
  • flat() перетворює матрицю на одновимірний масив, коли індекси не потрібні.
  • reduce() підходить для агрегації, наприклад суми всіх елементів.

Швидкий приклад

Усі приклади нижче працюють із цією матрицею:

javascript
const matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; for (const row of matrix) { for (const value of row) { console.log(value); // 1, 2, 3, 4, ... 9 } }

Класичний спосіб через for

javascript
for (let i = 0; i < matrix.length; i++) { for (let j = 0; j < matrix[i].length; j++) { console.log(`matrix[${i}][${j}] = ${matrix[i][j]}`); } }
  • i це індекс рядка,
  • j це індекс стовпця,
  • matrix[i][j] це елемент у рядку i та стовпці j.

Вивід:

javascript
matrix[0][0] = 1 matrix[0][1] = 2 // ... matrix[2][2] = 9

Цей варіант дає повний контроль: можна йти у зворотному напрямку, пропускати елементи, вийти через break або continue.

for...of і forEach()

for...of проходить по значеннях, тому код коротший:

javascript
for (const row of matrix) { for (const value of row) { console.log(value); } }

Зовнішній for...of іде по рядках, внутрішній по елементах усередині рядка. Це найчитабельніший і найсучасніший спосіб обходу, і його все ще можна перервати через break.

forEach() робить те саме у функціональному стилі й одразу дає індекси:

javascript
matrix.forEach((row, i) => { row.forEach((value, j) => { console.log(`matrix[${i}][${j}] = ${value}`); }); });

Він не потребує ручного лічильника і добре лягає у функціональний стиль, але перервати його через break або return не вийде: return лише завершує поточний виклик колбека.

flat(), коли індекси не потрібні

Якщо треба пройтися по всіх елементах поспіль, матрицю можна «розгорнути»:

javascript
matrix.flat().forEach(value => console.log(value));

flat() робить із двовимірного масиву звичайний одновимірний:

javascript
matrix.flat(); // [1, 2, 3, 4, 5, 6, 7, 8, 9]

Мінус у тому, що після цього ви втрачаєте інформацію про рядок і стовпець, а також створюєте новий масив у пам'яті.

reduce() для підрахунків

Якщо потрібно, наприклад, підсумувати всі елементи:

javascript
const sum = matrix.reduce( (acc, row) => acc + row.reduce((a, b) => a + b, 0), 0 ); console.log(sum); // 45

Внутрішній reduce підсумовує рядок, зовнішній збирає все разом.

Порівняння способів

СпосібЩо робитьЧи можна перервати цикл
forПовний контроль, індексиТак
for...ofПростий і читабельний обхідТак
forEach()Функціональний стильНі
flat() плюс forEach()Обхід усіх значень як одновимірного масивуНі
reduce()Агрегація, наприклад сумаТак, логічно

Підсумок: для обходу двовимірного масиву

javascript
for (const row of matrix) { for (const value of row) { console.log(value); } }

це сучасний, читабельний і безпечний спосіб.

Типові помилки

  • break усередині forEach(). Це синтаксична помилка, а return виходить лише з одного виклику колбека. Якщо потрібен ранній вихід, беріть for або for...of.
  • Один цикл замість двох. matrix.forEach(row => console.log(row)) виведе масиви, а не значення; для значень потрібен другий рівень обходу.
  • Межа за matrix[0].length. На «рваних» масивах із рядками різної довжини це або пропустить елементи, або дасть undefined; беріть matrix[i].length.
  • for...in замість for...of. for...in перебирає ключі, тобто рядкові індекси "0", "1", і ще й підхоплює власні перелічувані властивості масиву.
  • flat() там, де потрібні координати. Після вирівнювання неможливо сказати, з якого рядка прийшло значення.
  • Зміна довжини масиву під час обходу. push або splice усередині циклу зсуває індекси і призводить до пропущених чи повторених елементів.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.