Google Apps Script: Как работать с массивом массивов?

Что такое массив массивов (двумерный массив)?

Массив массивов, также известный как двумерный массив, представляет собой структуру данных, в которой каждый элемент массива сам является массивом. Другими словами, это массив, содержащий другие массивы в качестве своих элементов. Это позволяет организовать данные в виде таблицы, где строки представлены внутренними массивами, а столбцы — элементами этих внутренних массивов.

Зачем использовать массивы массивов в 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);
  }
}

Добавить комментарий