Что такое массив массивов (двумерный массив)?
Массив массивов, также известный как двумерный массив, представляет собой структуру данных, в которой каждый элемент массива сам является массивом. Другими словами, это массив, содержащий другие массивы в качестве своих элементов. Это позволяет организовать данные в виде таблицы, где строки представлены внутренними массивами, а столбцы — элементами этих внутренних массивов.
Зачем использовать массивы массивов в Google Apps Script?
Массивы массивов незаменимы, когда необходимо работать с табличными данными, такими как данные из Google Sheets, CSV-файлов или любых других источников, где информация организована в строки и столбцы. Они позволяют:
Представлять и обрабатывать данные табличной структуры.
Реализовывать матрицы и другие математические структуры.
Упрощать сложные операции, такие как сортировка, фильтрация и агрегация данных.
Эффективно хранить и манипулировать взаимосвязанными данными.
Объявление и инициализация массива массивов
В Google Apps Script массив массивов можно объявить и инициализировать несколькими способами. Вот некоторые примеры:
/**
* Объявление и инициализация массива массивов.
* @returns {Array<Array>}
*/
function initializeArrayOfArrays(): Array<Array> {
// 1. Инициализация с помощью литерала массива
let matrix: Array<Array> = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// 2. Создание пустого массива и заполнение его массивами
let anotherMatrix: Array<Array> = [];
anotherMatrix.push([10, 11, 12]);
anotherMatrix.push([13, 14, 15]);
// 3. Создание массива определенного размера и заполнение значениями
let sizedMatrix: Array<Array> = new Array(3);
for (let i = 0; i < sizedMatrix.length; i++) {
sizedMatrix[i] = new Array(3).fill(0); // Заполняем нулями
}
return matrix;
}Работа с элементами массива массивов
Доступ к элементам массива массивов по индексу
Для доступа к элементу массива массивов используется двойная индексация. Первый индекс указывает на строку (внутренний массив), а второй индекс — на столбец (элемент внутри внутреннего массива). Индексация начинается с 0.
/**
* Доступ к элементу массива массивов.
*/
function accessArrayElement(): void {
let matrix: Array<Array> = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
let element: number = matrix[1][2]; // Доступ к элементу во второй строке и третьем столбце (значение: 6)
Logger.log(element);
}Изменение элементов массива массивов
Изменение элементов выполняется аналогично доступу, только используется оператор присваивания =.
/**
* Изменение элемента массива массивов.
*/
function modifyArrayElement(): void {
let matrix: Array<Array> = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
matrix[0][0] = 100; // Изменяем элемент в первой строке и первом столбце
Logger.log(matrix);
}Добавление и удаление строк и столбцов
Для добавления и удаления строк используются методы push() (добавление в конец) и splice() (добавление/удаление в произвольном месте). Добавление и удаление столбцов требует более сложной логики, так как необходимо модифицировать каждый внутренний массив.
/**
* Добавление строки в массив массивов.
*/
function addRowToArray(): void {
let matrix: Array<Array> = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
matrix.push([10, 11, 12]); // Добавляем новую строку в конец
Logger.log(matrix);
}
/**
* Добавление столбца в массив массивов.
*/
function addColumnToArray(): void {
let matrix: Array<Array> = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
for (let i = 0; i < matrix.length; i++) {
matrix[i].push(10 + i); // Добавляем новый столбец с разными значениями
}
Logger.log(matrix);
}Итерация по массиву массивов
Использование циклов `for` для перебора элементов
Наиболее распространенный способ перебора элементов массива массивов — использование вложенных циклов for. Внешний цикл перебирает строки, а внутренний — столбцы.
/**
* Итерация по массиву массивов с использованием циклов for.
*/
function iterateWithForLoops(): void {
let matrix: Array<Array> = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
Logger.log(`Element at [${i}][${j}]: ${matrix[i][j]}`);
}
}
}Использование метода `forEach` для перебора элементов
Метод forEach также можно использовать для перебора элементов, но он менее удобен для двумерных массивов, так как требует вложенных вызовов forEach.
/**
* Итерация по массиву массивов с использованием метода forEach.
*/
function iterateWithForEach(): void {
let matrix: Array<Array> = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
matrix.forEach(function(row, rowIndex) {
row.forEach(function(element, columnIndex) {
Logger.log(`Element at [${rowIndex}][${columnIndex}]: ${element}`);
});
});
}Примеры итерации для различных задач
Пример: суммирование всех элементов массива массивов.
/**
* Суммирование элементов массива массивов.
* @param {Array<Array>} matrix - Массив массивов чисел.
* @returns {number} - Сумма всех элементов.
*/
function sumMatrixElements(matrix: Array<Array>): number {
let sum: number = 0;
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
sum += matrix[i][j];
}
}
return sum;
}Примеры использования массивов массивов в Google Apps Script
Чтение данных из Google Sheets в массив массивов
/**
* Чтение данных из Google Sheets в массив массивов.
* @returns {Array<Array>} - Массив массивов, содержащий данные из таблицы.
*/
function readDataFromSheet(): Array<Array> {
let ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getActiveSheet();
let range = sheet.getDataRange();
let values = range.getValues();
return values;
}Запись данных из массива массивов в Google Sheets
/**
* Запись данных из массива массивов в Google Sheets.
* @param {Array<Array>} data - Массив массивов для записи в таблицу.
*/
function writeDataToSheet(data: Array<Array>): void {
let ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getActiveSheet();
let range = sheet.getRange(1, 1, data.length, data[0].length);
range.setValues(data);
}Обработка и фильтрация данных в массиве массивов
Пример: фильтрация строк, где первый элемент больше заданного значения.
/**
* Фильтрация строк массива массивов.
* @param {Array<Array>} data - Массив массивов для фильтрации.
* @param {number} threshold - Пороговое значение для первого элемента строки.
* @returns {Array<Array>} - Отфильтрованный массив массивов.
*/
function filterData(data: Array<Array>, threshold: number): Array<Array> {
let filteredData: Array<Array> = data.filter(function(row) {
return row[0] > threshold;
});
return filteredData;
}Реализация алгоритмов с использованием массивов массивов (например, сортировка)
Пример: Сортировка строк массива массивов по первому элементу.
/**
* Сортировка массива массивов по первому элементу каждой строки.
* @param {Array<Array>} data - Массив массивов для сортировки.
* @returns {Array<Array>} - Отсортированный массив массивов.
*/
function sortData(data: Array<Array>): Array<Array> {
data.sort(function(a, b) {
if (a[0] b[0]) return 1;
return 0;
});
return data;
}Оптимизация работы с массивами массивов
Эффективное использование памяти при работе с большими массивами
При работе с большими массивами массивов важно учитывать использование памяти. Старайтесь не создавать лишних копий массивов и освобождать память, когда данные больше не нужны. Используйте итераторы, если возможно, вместо полной загрузки данных в память.
Советы по оптимизации скорости выполнения операций
Избегайте частого изменения размеров массива, так как это может привести к перераспределению памяти и снижению производительности.
Предварительно определите размер массива, если он известен.
Используйте встроенные методы для обработки данных, такие как map, filter и reduce, так как они часто оптимизированы для скорости.
Минимизируйте количество операций в циклах, особенно во вложенных циклах.
Обработка ошибок и отладка
При работе с массивами массивов важно предусматривать обработку ошибок, таких как выход за границы массива. Используйте try...catch блоки для обработки исключений и Logger.log() для отладки.
/**
* Пример обработки ошибок при доступе к элементу массива.
*/
function safeAccess(): void {
let matrix: Array<Array> = [[1, 2], [3, 4]];
try {
let value = matrix[5][0]; // Попытка доступа к несуществующему элементу
Logger.log(value);
} catch (e) {
Logger.log("Ошибка: " + e);
}
}