Google Apps Script: Как создать пустой массив?

Что такое массив и зачем он нужен?

Массив в Google Apps Script, как и в JavaScript, представляет собой упорядоченную коллекцию значений. Каждый элемент в массиве имеет свой числовой индекс, начиная с нуля. Массивы являются фундаментальной структурой данных, необходимой для хранения наборов однотипных или разнотипных данных, их итерации и обработки. Они широко используются при работе с данными из Google Таблиц, Документов, Календаря и других сервисов Google Workspace, а также при обработке ответов API.

Объявление и инициализация массивов: основы

Объявление массива в Apps Script следует стандартному синтаксису JavaScript. Можно объявить массив и сразу инициализировать его значениями:

/**
 * Пример объявления и инициализации массива строк.
 */
function declareAndInitializeArray(): void {
  // Объявляем массив строк с начальными значениями
  const campaignNames: string[] = ["Поиск - Бренд", "КМС - Ремаркетинг", "Поиск - Общие запросы"];
  Logger.log(campaignNames);
  Logger.log(typeof campaignNames); // object
  Logger.log(Array.isArray(campaignNames)); // true
}

Использование типизации (например, : string[]) помогает улучшить читаемость кода и избежать ошибок на этапе разработки.

Создание пустого массива: основные способы

Часто возникает необходимость создать массив, который будет наполняться данными позже в процессе выполнения скрипта. Существует два основных способа создания пустого массива.

Использование литерала массива: `[]`

Самый распространенный, лаконичный и рекомендуемый способ создания пустого массива — использование литеральной нотации [].

/**
 * Создание пустого массива с использованием литерала.
 */
function createEmptyArrayLiteral(): void {
  // Создаем пустой массив для хранения ID конверсий
  const conversionIds: number[] = [];
  Logger.log(conversionIds);      // Вывод: []
  Logger.log(conversionIds.length); // Вывод: 0
}

Этот способ прост, понятен и эффективен.

Применение конструктора `new Array()`

Альтернативный способ — использование конструктора Array().

/**
 * Создание пустого массива с использованием конструктора Array().
 */
function createEmptyArrayConstructor(): void {
  // Создаем пустой массив для хранения объектов отчетов
  const reportObjects: object[] = new Array();
  Logger.log(reportObjects);      // Вывод: []
  Logger.log(reportObjects.length); // Вывод: 0
}

Вызов new Array() без аргументов создает пустой массив, аналогично [].

Различия между способами создания пустого массива

При создании именно пустого массива между [] и new Array() практически нет разницы в функциональности. Однако литеральная нотация [] считается более предпочтительной по нескольким причинам:

Краткость и читаемость: [] короче и интуитивно понятнее.

Производительность: В большинстве движков JavaScript литеральная нотация может быть незначительно быстрее.

Поведение конструктора с аргументами: Важно помнить, что new Array(n), где n — число, создает массив с n пустыми слотами (empty slots), а не массив с одним числовым элементом n. Это может привести к путанице. new Array("a", "b") работает аналогично ["a", "b"].

В подавляющем большинстве случаев для создания пустого массива следует использовать [].

Работа с пустым массивом: добавление элементов

После создания пустого массива его необходимо наполнить данными.

Метод `push()`: добавление элементов в конец массива

Метод push() является стандартным способом добавления одного или нескольких элементов в конец массива. Он изменяет исходный массив и возвращает его новую длину.

/**
 * Добавление элементов в массив с помощью push().
 */
function addElementsWithPush(): void {
  const keywords: string[] = [];
  Logger.log(`Начальная длина: ${keywords.length}`); // 0

  // Добавляем элементы
  let newLength = keywords.push("google apps script tutorial");
  Logger.log(`Добавлен элемент: ${keywords[0]}, Новая длина: ${newLength}`); // 1

  newLength = keywords.push("apps script automation", "gas examples");
  Logger.log(`Массив после добавления: ${keywords}`);
  Logger.log(`Новая длина: ${newLength}`); // 3
}

Добавление элементов по индексу

Можно добавлять элементы, присваивая значение конкретному индексу массива. Если присвоить значение индексу, равному текущей длине массива, элемент добавится в конец, аналогично push().

/**
 * Добавление элементов в массив по индексу.
 */
function addElementsByIndex(): void {
  const campaignData: object[] = [];

  // Добавляем первый элемент (индекс 0)
  campaignData[0] = { id: "C123", name: "Search Campaign", budget: 50 };
  Logger.log(`Массив после индекса 0: ${JSON.stringify(campaignData)}`);
  Logger.log(`Длина: ${campaignData.length}`); // 1

  // Добавляем следующий элемент (индекс 1)
  campaignData[1] = { id: "C456", name: "Display Campaign", budget: 30 };
  Logger.log(`Массив после индекса 1: ${JSON.stringify(campaignData)}`);
  Logger.log(`Длина: ${campaignData.length}`); // 2

  // Осторожно: Создание 'дыр' в массиве
  campaignData[5] = { id: "C789", name: "Video Campaign", budget: 70 };
  Logger.log(`Массив после индекса 5: ${JSON.stringify(campaignData)}`);
  Logger.log(`Длина: ${campaignData.length}`); // 6 (индексы 2, 3, 4 будут )
  Logger.log(campaignData[3]); // undefined
}

Присваивание значения индексу, который значительно превышает текущую длину, создает разреженный массив (sparse array), что обычно не рекомендуется.

Примеры добавления различных типов данных в пустой массив

Массивы в Apps Script могут хранить элементы различных типов данных.

/**
 * Добавление различных типов данных в массив.
 */
function addMixedDataTypes(): void {
  const mixedData: any[] = [];

  mixedData.push("Строковый элемент"); // string
  mixedData.push(123.45);              // number
  mixedData.push(true);                // boolean
  mixedData.push(null);                // null
  mixedData.push({ key: "value" });     // object
  mixedData.push(new Date());          // Date object

  Logger.log(`Смешанный массив: ${JSON.stringify(mixedData)}`);
  Logger.log(`Длина: ${mixedData.length}`); // 6
}

Распространенные ошибки и как их избежать

При работе с пустыми массивами можно столкнуться с некоторыми типичными ошибками.

Реклама

Попытка доступа к несуществующему индексу в пустом массиве

Обращение к любому индексу пустого массива вернет undefined. Если попытаться использовать это значение в дальнейших операциях, это может привести к ошибке TypeError.

/**
 * Пример ошибки при доступе к элементу пустого массива.
 */
function accessEmptyArrayError(): void {
  const empty: string[] = [];
  try {
    const firstElement: string = empty[0];
    Logger.log(firstElement); // Не выполнится, т.к. firstElement = undefined
    // Ошибка возникнет при попытке использовать метод строки на undefined
    Logger.log(firstElement.toUpperCase()); 
  } catch (e) {
    Logger.log(`Ошибка: ${e}`); // TypeError: Cannot read property 'toUpperCase' of undefined
  }
  
  // Правильно: проверять длину перед доступом
  if (empty.length > 0) {
     const firstElement: string = empty[0];
     // ... работа с элементом
  } else {
     Logger.log("Массив пуст, доступ к элементу невозможен.");
  }
}

Неправильное использование методов массивов

Некоторые методы массива (например, pop(), shift(), forEach(), map(), filter()) ведут себя специфично на пустых массивах:

pop() и shift() вернут undefined и не изменят массив.

Итерационные методы (forEach, map, filter, reduce и т.д.) просто не выполнят ни одной итерации, не вызвав ошибки.

Проблема может возникнуть, если вы ожидаете, что метод вернет значение или выполнит действие, а он ничего не делает из-за пустоты массива.

Советы по отладке кода при работе с пустыми массивами

Используйте Logger.log() или console.log(): Выводите содержимое массива и его длину (array.length) в ключевых точках алгоритма, особенно перед циклами или доступом по индексу.

Проверяйте Array.isArray(): Убедитесь, что переменная действительно содержит массив.

Используйте отладчик Apps Script: Устанавливайте точки останова (breakpoints) и пошагово выполняйте код, отслеживая значения переменных.

Проверяйте длину: Перед итерацией или доступом к элементам добавьте проверку if (myArray.length > 0) { ... }.

Практические примеры использования пустых массивов

Пустые массивы часто служат контейнерами для сбора и обработки данных.

Сбор данных из таблицы Google Sheets в пустой массив

/**
 * Собирает email'ы из указанного столбца таблицы Google Sheets.
 * @param {string} sheetName Имя листа.
 * @param {number} emailColumn Номер столбца с email (начиная с 1).
 * @return {string[]} Массив email-адресов.
 */
function getEmailsFromSheet(sheetName: string = "Лист1", emailColumn: number = 3): string[] {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(sheetName);
  if (!sheet) {
    Logger.log(`Лист с именем '${sheetName}' не найден.`);
    return []; // Возвращаем пустой массив, если лист не найден
  }

  const dataRange = sheet.getDataRange();
  const values = dataRange.getValues();

  const emails: string[] = []; // Создаем пустой массив для результатов

  // Пропускаем заголовок (i=1)
  for (let i = 1; i < values.length; i++) {
    const row = values[i];
    const email = row[emailColumn - 1]; // Индексация в массиве с 0

    // Простая проверка на валидность email и непустое значение
    if (email && typeof email === 'string' && email.includes('@')) {
      emails.push(email.trim());
    }
  }

  Logger.log(`Найдено ${emails.length} email адресов.`);
  return emails;
}

Фильтрация данных и добавление результатов в новый пустой массив

/**
 * Фильтрует массив объектов кампаний по бюджету.
 * @param {{id: string, name: string, budget: number}[]} campaigns Массив объектов кампаний.
 * @param {number} minBudget Минимальный бюджет.
 * @return {{id: string, name: string, budget: number}[]} Отфильтрованный массив кампаний.
 */
function filterCampaignsByBudget(campaigns: {id: string, name: string, budget: number}[], minBudget: number): {id: string, name: string, budget: number}[] {
  
  const filteredCampaigns: {id: string, name: string, budget: number}[] = []; // Пустой массив для результатов фильтрации

  for (const campaign of campaigns) {
    if (campaign.budget >= minBudget) {
      filteredCampaigns.push(campaign);
    }
  }

  // Альтернатива с использованием Array.prototype.filter
  // const filteredCampaigns = campaigns.filter(campaign => campaign.budget >= minBudget);

  Logger.log(`Кампаний с бюджетом >= ${minBudget}: ${filteredCampaigns.length}`);
  return filteredCampaigns;
}

/** Пример использования функции фильтрации */
function testCampaignFilter(): void {
   const allCampaigns = [
     { id: "C1", name: "Search Low Budget", budget: 20 },
     { id: "C2", name: "Search High Budget", budget: 150 },
     { id: "C3", name: "Display Medium Budget", budget: 75 }
   ];
   const highBudgetCampaigns = filterCampaignsByBudget(allCampaigns, 100);
   Logger.log(JSON.stringify(highBudgetCampaigns)); 
}

Обработка данных и создание массива для дальнейшего использования

Предположим, мы получили ответ от внешнего API в виде массива объектов, и нам нужно извлечь только определенные поля.

/**
 * Извлекает UTM-метки из массива URL-адресов.
 * @param {string[]} urls Массив URL.
 * @return {{source: string | null, medium: string | null, campaign: string | null}[]} Массив объектов с UTM-метками.
 */
function extractUtmTags(urls: string[]): {source: string | null, medium: string | null, campaign: string | null}[] {
  
  const utmResults: {source: string | null, medium: string | null, campaign: string | null}[] = []; // Пустой массив для хранения результатов

  for (const urlString of urls) {
    try {
      const url = new URL(urlString); // Используем встроенный объект URL для парсинга
      const params = url.searchParams;
      
      const utm = {
        source: params.get('utm_source'),
        medium: params.get('utm_medium'),
        campaign: params.get('utm_campaign')
      };
      utmResults.push(utm);
    } catch (e) {
      Logger.log(`Не удалось распарсить URL: ${urlString}. Ошибка: ${e}`);
      // Можно добавить объект с null значениями или пропустить
      utmResults.push({ source: null, medium: null, campaign: null }); 
    }
  }
  return utmResults;
}

/** Пример использования */
function testUtmExtraction(): void {
  const landingPages = [
    "https://example.com/?utm_source=google&utm_medium=cpc&utm_campaign=spring_sale",
    "https://example.com/about",
    "https://example.com/?utm_source=facebook&utm_medium=cpm",
    "invalid-url"
  ];
  const extractedTags = extractUtmTags(landingPages);
  Logger.log(JSON.stringify(extractedTags, null, 2));
}

В этих примерах пустой массив инициализируется в начале, а затем динамически наполняется данными в процессе выполнения логики скрипта, что является типичным паттерном использования в Google Apps Script.


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