GAS: オブジェクトの配列を二次元配列にしてシートに貼りつける

前回の記事でふれたとおり、Google Apps Scriptでスプレッドシートの表を扱う時、二次元配列のままでは可読性が低いので、オブジェクト(の配列)に変換して処理したりしています。

例: 変換前(二次元配列)

[
  ['name', 'kana', 'position', 'gender'],
  ['神田 庸司', 'カンダ ヨウジ', '役員', '男'],
  ['米田 麻琴', 'マイタ マコト', '部長', '女'],
  ['辻 宜昭', 'ツジ ヨシアキ', '課長', '男']
]

例: 変換後(オブジェクトの配列)

[
  { name: '神田 庸司', kana: 'カンダ ヨウジ', position: '役員', gender: '男'},
  { name: '米田 麻琴', kana: 'マイタ マコト', position: '部長', gender: '女'},
  { name: '辻 宜昭', kana: 'ツジ ヨシアキ', position: '課長', gender: '男'}
]

このように、表をオブジェクトの配列に変換して作業したりした後、シートにデータを貼りつけたい場合は、二次元配列に変換する必要があります。
(その他、Web APIなどから取ってきたJSONをシートに貼りつける時なども。)

そんな時に使えるコードを紹介します。

すべてのオブジェクトが同じプロパティを持つ場合

すべてのオブジェクトが確実に同じプロパティを持つ場合は、下記のコードが使えます。
(この例では、各オブジェクトは必ずname, kana, position, genderの4つのプロパティを持っています。)

function sample() {
  // オブジェクトの配列
  const objects = [
    { name: '神田 庸司', kana: 'カンダ ヨウジ', position: '役員', gender: '男'},
    { name: '米田 麻琴', kana: 'マイタ マコト', position: '部長', gender: '女'},
    { name: '辻 宜昭', kana: 'ツジ ヨシアキ', position: '課長', gender: '男'}
  ]

  // オブジェクトの配列 → 二次元配列
  const arrays = objectsToArrays(objects);

  // シートに貼りつける
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = spreadsheet.getSheetByName('シート名');
  sheet.getRange(1, 1, arrays.length, arrays[0].length).setValues(arrays);  
}

/**
 * オブジェクトの配列から二次元配列を作成する
 */
function objectsToArrays(objects) {
  const keys = Object.keys(objects[0]);
  const records = objects.map(object => 
    keys.map(key => object[key])
  );
  return [keys, ...records];
}
無事にシートに貼りつけできました

オブジェクトが同じプロパティを持つとは限らない場合

すべてのオブジェクトが同じプロパティを持つとは限らない場合、下記のコードで対応できます。
(この例では、position, genderプロパティを持たないオブジェクトがあります)

function sample() {
  // オブジェクトの配列
  const objects = [
    { name: '神田 庸司', kana: 'カンダ ヨウジ'},
    { name: '米田 麻琴', kana: 'マイタ マコト', position: '部長'},
    { name: '辻 宜昭', kana: 'ツジ ヨシアキ', gender: '男'},
  ];

  // オブジェクトの配列 → 二次元配列
  const arrays = objectsToArrays(objects);

  // シートに貼りつける
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = spreadsheet.getSheetByName('シート名');
  sheet.getRange(1, 1, arrays.length, arrays[0].length).setValues(arrays);  
}

/**
 * オブジェクトの配列から二次元配列を作成する
 */
function objectsToArrays(objects) {
  const keys = objects.reduce((acc, object) => {
    const newKeys = Object.keys(object).filter(key => !acc.includes(key));
    return newKeys.length ? [...acc, ...newKeys] : acc;
  }, []);

  const records = objects.map(object => 
    keys.map(key => object[key])
  );
  return [keys, ...records];
}
オブジェクトごとにプロパティが異なっても、適切にシートに貼り付けることができた。

コメント