Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Обхід двовимірного масиву». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Двовимірний масив це масив масивів, тому обходять його вкладеними циклами: зовнішній іде по рядках, внутрішній по стовпцях.** Найчитабельніший сучасний варіант це два вкладені `for...of`; класичний `for` потрібен, коли важливі індекси, а `flat()` і `reduce()` зручні, коли треба пройтися по всіх значеннях поспіль або згорнути їх в одне число. ```javascript for (const row of matrix) { for (const value of row) { console.log(value); } } ``` **Ключове:** вкладений обхід, і пам'ятайте, що `forEach()` не можна перервати через `break`.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Обхід двовимірного масиву (матриці) це одна з базових, але дуже важливих операцій.** Оскільки це масив масивів, його обходять вкладеними циклами: зовнішній іде по рядках, внутрішній по стовпцях. Спосіб обходу обирають за тим, чи потрібні індекси і чи треба мати змогу перервати цикл. ## Теорія ### 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` усередині циклу зсуває індекси і призводить до пропущених чи повторених елементів.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.