Как работать с ключами объектов в Google Apps Script: подробное руководство

Что такое ключи объектов и зачем они нужны

В Google Apps Script, как и в JavaScript, объекты играют центральную роль в представлении данных. Ключи объектов – это идентификаторы, позволяющие получать доступ к конкретным значениям, хранящимся внутри объекта. Понимание работы с ключами необходимо для эффективной манипуляции данными, особенно при работе с API Google Workspace, которые часто возвращают данные в формате объектов.

Объекты как ассоциативные массивы: основы

Объекты в JavaScript можно рассматривать как ассоциативные массивы или словари. В отличие от обычных массивов, где доступ к элементам осуществляется по числовому индексу, в объектах доступ к значениям осуществляется по строковым ключам. Эти ключи должны быть строками (или символами), и они однозначно идентифицируют каждое свойство объекта. Например, объект, представляющий информацию о рекламной кампании, может иметь ключи "campaignId", "name", "status", "budget".

Обзор основных методов работы с ключами объектов

Для работы с ключами объектов в Google Apps Script предусмотрены несколько основных инструментов:

Object.keys(obj): Возвращает массив всех ключей объекта.

for...in: Цикл, позволяющий перебрать все ключи объекта.

hasOwnProperty(key): Метод, позволяющий проверить, существует ли ключ в объекте (не в прототипе).

Оператор delete: Удаляет ключ и соответствующее ему значение из объекта.

Получение ключей объекта в Google Apps Script

Использование метода `Object.keys()`

Метод Object.keys() – наиболее прямой способ получить массив всех ключей объекта. Он возвращает массив строк, представляющих имена всех перечисляемых собственных свойств объекта.

/**
 * Возвращает массив ключей объекта.
 *
 * @param {object} obj Объект, ключи которого нужно получить.
 * @return {string[]} Массив ключей объекта.
 */
function getObjectKeys(obj: object): string[] {
  return Object.keys(obj);
}

// Пример использования
const campaign = { campaignId: '123', name: 'Summer Campaign', status: 'active' };
const keys = getObjectKeys(campaign); // keys будет равен ['campaignId', 'name', 'status']
Logger.log(keys);

Итерация по ключам объекта с помощью цикла `for…in`

Цикл for...in позволяет перебрать все перечисляемые свойства объекта, включая унаследованные свойства из прототипа. Чтобы избежать нежелательной обработки унаследованных свойств, рекомендуется использовать метод hasOwnProperty().

/**
 * Итерирует по ключам объекта, выполняя заданную функцию для каждого ключа.
 *
 * @param {object} obj Объект, по ключам которого нужно итерировать.
 * @param {function(string, any): void} callback Функция, вызываемая для каждого ключа и значения.
 */
function iterateObjectKeys(obj: object, callback: (key: string, value: any) => void): void {
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      callback(key, obj[key]);
    }
  }
}

// Пример использования
const adGroup = { adGroupId: '456', name: 'Targeting Keywords', status: 'paused' };
iterateObjectKeys(adGroup, function(key, value) {
  Logger.log('Key: ' + key + ', Value: ' + value);
});

Различия и особенности использования `Object.keys()` и `for…in`

Object.keys() возвращает только собственные ключи объекта в виде массива. Это делает его удобным для случаев, когда нужно получить список ключей для дальнейшей обработки (например, для фильтрации или преобразования).

for...in перебирает все перечисляемые свойства, включая унаследованные. Требует дополнительной проверки hasOwnProperty() для исключения унаследованных свойств. Более подходит для ситуаций, когда нужно выполнить какие-либо действия для каждого ключа и значения в объекте.

В большинстве случаев рекомендуется использовать Object.keys() для получения списка ключей и for...in для перебора свойств объекта с обязательной проверкой hasOwnProperty(). Однако, если важна производительность и заранее известно, что объект не имеет унаследованных свойств, можно использовать for...in без проверки.

Работа с ключами объектов: примеры использования

Проверка наличия ключа в объекте

Для проверки наличия ключа в объекте можно использовать метод hasOwnProperty() или оператор in.

/**
 * Проверяет, существует ли ключ в объекте.
 *
 * @param {object} obj Объект, в котором нужно проверить наличие ключа.
 * @param {string} key Ключ, наличие которого нужно проверить.
 * @return {boolean} `true`, если ключ существует, иначе `false`.
 */
function hasKey(obj: object, key: string): boolean {
  return obj.hasOwnProperty(key);
  // Альтернативный вариант: return key in obj;
}

// Пример использования
const keyword = { keywordId: '789', text: 'best deals', status: 'enabled' };
const hasText = hasKey(keyword, 'text'); // hasText будет равен true
const hasBid = hasKey(keyword, 'bid');   // hasBid будет равен false
Logger.log(hasText);
Logger.log(hasBid);

Доступ к значениям объекта через ключи

Доступ к значениям объекта осуществляется с помощью квадратных скобок [] и имени ключа.

/**
 * Возвращает значение объекта по заданному ключу.
 *
 * @param {object} obj Объект, из которого нужно получить значение.
 * @param {string} key Ключ, по которому нужно получить значение.
 * @return {any} Значение объекта по заданному ключу, или `undefined`, если ключ не существует.
 */
function getValueByKey(obj: object, key: string): any {
  return obj[key];
}

// Пример использования
const ad = { adId: '101', headline: 'Amazing Offer', description: 'Limited time only!' };
const headline = getValueByKey(ad, 'headline'); // headline будет равен 'Amazing Offer'
Logger.log(headline);

Фильтрация объектов на основе ключей

Ключи можно использовать для фильтрации объектов. Например, можно создать новый объект, содержащий только определенные ключи из исходного объекта.

/**
 * Фильтрует объект, оставляя только заданные ключи.
 *
 * @param {object} obj Объект, который нужно отфильтровать.
 * @param {string[]} keys Массив ключей, которые нужно оставить.
 * @return {object} Новый объект, содержащий только заданные ключи и их значения.
 */
function filterObjectByKeys(obj: object, keys: string[]): object {
  const filteredObj: { [key: string]: any } = {};
  for (const key of keys) {
    if (obj.hasOwnProperty(key)) {
      filteredObj[key] = obj[key];
    }
  }
  return filteredObj;
}

// Пример использования
const campaignData = { campaignId: '123', name: 'Back to School', status: 'active', budget: 1000, startDate: '2024-08-01' };
const selectedKeys = ['campaignId', 'name', 'status'];
const filteredData = filterObjectByKeys(campaignData, selectedKeys);
// filteredData будет равен { campaignId: '123', name: 'Back to School', status: 'active' }
Logger.log(filteredData);
Реклама

Преобразование объектов с использованием ключей

Ключи объектов часто используются для преобразования формата данных, например, при интеграции с внешними API или при подготовке данных для отчетов.

/**
 * Преобразует объект, меняя ключи на новые значения.
 *
 * @param {object} obj Объект, который нужно преобразовать.
 * @param {object} keyMap Объект, где ключи - старые ключи, а значения - новые ключи.
 * @return {object} Новый объект с измененными ключами.
 */
function transformObjectKeys(obj: object, keyMap: { [key: string]: string }): object {
  const transformedObj: { [key: string]: any } = {};
  for (const oldKey in obj) {
    if (obj.hasOwnProperty(oldKey)) {
      const newKey = keyMap[oldKey] || oldKey; // Если нового ключа нет, используем старый
      transformedObj[newKey] = obj[oldKey];
    }
  }
  return transformedObj;
}

// Пример использования
const adwordsData = { campaign_id: '123', campaign_name: 'Summer Sales', campaign_status: 'ENABLED' };
const keyMap = { campaign_id: 'campaignId', campaign_name: 'name', campaign_status: 'status' };
const transformedData = transformObjectKeys(adwordsData, keyMap);
// transformedData будет равен { campaignId: '123', name: 'Summer Sales', status: 'ENABLED' }
Logger.log(transformedData);

Удаление и добавление ключей в объекте

Удаление ключа с помощью оператора `delete`

Оператор delete используется для удаления ключа и соответствующего ему значения из объекта.

/**
 * Удаляет ключ из объекта.
 *
 * @param {object} obj Объект, из которого нужно удалить ключ.
 * @param {string} key Ключ, который нужно удалить.
 */
function deleteKey(obj: object, key: string): void {
  delete obj[key];
}

// Пример использования
const campaignSettings = { campaignId: '123', budget: 1000, startDate: '2024-08-01', endDate: '2024-08-31' };
deleteKey(campaignSettings, 'endDate');
// campaignSettings теперь будет равен { campaignId: '123', budget: 1000, startDate: '2024-08-01' }
Logger.log(campaignSettings);

Добавление новых ключей и значений

Новые ключи и значения добавляются в объект с помощью оператора присваивания =.

/**
 * Добавляет новый ключ и значение в объект.
 *
 * @param {object} obj Объект, в который нужно добавить ключ и значение.
 * @param {string} key Ключ, который нужно добавить.
 * @param {any} value Значение, которое нужно добавить.
 */
function addKeyValue(obj: object, key: string, value: any): void {
  obj[key] = value;
}

// Пример использования
const newCampaign = { campaignId: '456', name: 'Holiday Promotion' };
addKeyValue(newCampaign, 'budget', 500);
// newCampaign теперь будет равен { campaignId: '456', name: 'Holiday Promotion', budget: 500 }
Logger.log(newCampaign);

Переименование ключей в объекте

Переименование ключа требует создания нового ключа с новым именем, присваивания ему значения старого ключа и последующего удаления старого ключа.

/**
 * Переименовывает ключ в объекте.
 *
 * @param {object} obj Объект, в котором нужно переименовать ключ.
 * @param {string} oldKey Старый ключ.
 * @param {string} newKey Новый ключ.
 */
function renameKey(obj: object, oldKey: string, newKey: string): void {
  if (obj.hasOwnProperty(oldKey)) {
    obj[newKey] = obj[oldKey];
    delete obj[oldKey];
  }
}

// Пример использования
const product = { product_id: '789', product_name: 'Premium Plan' };
renameKey(product, 'product_name', 'name');
// product теперь будет равен { product_id: '789', name: 'Premium Plan' }
Logger.log(product);

Продвинутые техники работы с ключами объектов

Использование деструктуризации объектов для работы с ключами

Деструктуризация объектов позволяет извлекать значения объекта по ключам в отдельные переменные.

/**
 * Использует деструктуризацию для извлечения значений из объекта.
 *
 * @param {object} obj Объект, из которого нужно извлечь значения.
 * @return {{id: string, name: string}} Объект с извлеченными значениями.
 */
function destructureObject(obj: {id: string, name: string}): {id: string, name: string} {
  const { id, name } = obj;
  return {id: id, name: name}; //Возвращаем, чтобы показать пример, в реальном коде это было бы излишне
}

// Пример использования
const user = { id: '123', name: 'John Doe', email: 'john.doe@example.com' };
const { id, name } = user; // id будет равен '123', name будет равен 'John Doe'
Logger.log(id);
Logger.log(name);

Работа с вложенными объектами и их ключами

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

/**
 * Рекурсивно получает все ключи из вложенного объекта.
 *
 * @param {object} obj Объект, из которого нужно получить ключи.
 * @param {string[]} keys (optional) Массив для хранения ключей.  Если не передан, создается новый массив.
 * @return {string[]} Массив всех ключей, включая ключи вложенных объектов.
 */
function getAllKeysRecursive(obj: object, keys: string[] = []): string[] {
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      keys.push(key);
      if (typeof obj[key] === 'object' && obj[key] !== null) {
        getAllKeysRecursive(obj[key], keys);
      }
    }
  }
  return keys;
}

// Пример использования
const account = { accountId: '1', details: { name: 'Acme Corp', address: { city: 'New York' } } };
const allKeys = getAllKeysRecursive(account);
// allKeys будет содержать ['accountId', 'details', 'name', 'address', 'city']
Logger.log(allKeys);

Применение ключей объектов в API Google Apps Script (Sheets, Docs, etc.)

Многие API Google Apps Script, такие как API таблиц (Sheets) и документов (Docs), возвращают данные в формате объектов. Понимание работы с ключами позволяет эффективно извлекать и обрабатывать эти данные.

Например, при работе с API таблиц можно получить данные ячейки в виде объекта, где ключи представляют свойства ячейки (значение, формат, и т.д.).

// Пример: получение данных о диапазоне из Google Sheets.
function getRangeData() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getActiveSheet();
  const range = sheet.getDataRange();
  const values = range.getValues();

  //Предположим, что первая строка - заголовки, а остальные - данные.
  const headers = values[0];

  for (let i = 1; i < values.length; i++) {
    const rowData = {};
    for (let j = 0; j < headers.length; j++) {
      rowData[headers[j]] = values[i][j];
    }
    Logger.log(rowData); //Вывод объекта для каждой строки.
  }
}

В этом примере, headers (заголовки столбцов) используются в качестве ключей для создания объекта rowData для каждой строки таблицы. Это позволяет получить доступ к данным строки по имени столбца, что делает код более читаемым и понятным. Подобные подходы можно применять и с другими API Google Apps Script, где возвращаемые данные представлены в виде объектов.


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