Транспонирование 2D-массива в JavaScript: оптимизированный подход
Быстрый ответ
Транспонированием двумерного массива называют процедуру обмена местами его строк и столбцов. В JavaScript такую операцию возможно выполнить с помощью метода map()
:
const transpose = m => m[0].map((_, i) => m.map(row => row[i]));
Вот как её использовать:
const transposed = transpose([[1,2], [3,4]]);
// Результат: [[1,3], [2,4]]
Подробности использования метода map()
Метод map()
стоит в центре нашего внимания — мы применяем его для переорганизации элементов массива. Он позволяет аккуратно и в две строки кода выполнять операции с каждым элементом массива, преобразовывая строки и столбцы и созавая транспонированную матрицу.
Сокращение кода благодаря стрелочным функциям ES6
Стрелочные функции из ES6 дают возможность писать более краткое и элегантное выражение нашего кода. Они ещё позволяют лексически связать контекст this
:
const transpose = arr => arr[0].map((_,i) => arr.map(row => row[i]));
Таким образом, транспонирование выглядит ещё более лаконичным.
На месте транспонирование для квадратных матриц
Использование деструктуризации из ES6 дает нам возможность выполнять транспонирование на месте — это идеальное решение для квадратных матриц:
function transposeInPlace(m) {
for(let i = 0; i < m.length; i++) {
for(let j = i + 1; j < m[i].length; j++) {
[m[i][j], m[j][i]] = [m[j][i], m[i][j]];
}
}
}
Функциональное программирование с применением reduce()
Овладев функциональными концепциями, можно использовать reduce()
в сочетании с map()
для создания транспонированного массива:
const transposeWithReduce = matrix =>
matrix.reduce(
(prev, next) => next.map((item, i) =>
(prev[i] || []).concat(next[i])
), []
);
Помощь от Lodash: использование _.zip()
В JavaScript существует множество полезных библиотек, в частности lodash, где для транспонирования можно применить _.zip()
:
const _ = require('lodash');
const transposed = _.zip(...array);
Нативное решение на чистом JavaScript
Чистый JavaScript также эффективен для транспонирования и не требует подключения дополнительных библиотек:
const transpose = a => a[0].map((_, i) => a.map(row => row[i]));
Классический подход с использованием вложенных циклов
Традиционным подходом является использование вложенных циклов for. Он также хорошо решает задачу транспонирования:
function transpose(matrix) {
const rows = matrix.length, cols = matrix[0].length;
const transposed = [];
for (let j = 0; j < cols; j++) {
transposed[j] = new Array(rows);
for (let i = 0; i < rows; i++) {
transposed[j][i] = matrix[i][j];
}
}
return transposed;
}
Избегайте граничных случаев
Внимательно следите за особыми случаями при транспонировании:
- Непрямоугольные массивы могут привести к непредсказуемым результатам.
- Большие объемы данных требуют детального вложения работы и контроля производительности.
- Возможность изменения данных: убедитесь, что при работе с исходным массивом вы избегаете нежелательных побочных эффектов.
Визуализация
Иногда полезно визуализировать транспонирование как переворот сетки:
Оригинальная сетка:
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
Транспонированная сетка:
| 1 | 4 | 7 |
| 2 | 5 | 8 |
| 3 | 6 | 9 |
Ценные советы для совершенствования качества кода
Некоторые рекомендации для улучшения вашего кода транспонирования:
- Вместо переменных используйте константы для функций, которые не собираетесь переприсваивать.
- Оптимизируйте работу с большими матрицами и стремитесь к повторному использованию кода.
- Проведите тестирование различных методов, чтобы выбрать наиболее подходящий для вашего случая.
- Применение неизменяемых структур данных поможет контролировать состояние программы.
Полезные материалы
- Array.prototype.map() – MDN — узнать больше о методе map().
- Array.from() – MDN — познакомиться с подробностями работы Array.from().
- Методы массивов – JavaScript.Info — расширить знания о методах обработки массивов.
- Углубляемся в Map в JavaScript | от Брэндона Морелли | Codeburst — совершенствуйте свои навыки использования map().