[GAS]オブジェクトにフィルターをかけて抽出しよう はじめに Day1

obj1EffectiveGoogleAppsScript

どうも。つじけ(tsujikenzo)です。このシリーズでは「オブジェクトにフィルターをかけて抽出しよう」をお届けします。全3回でお送りします。

この記事は、#Effective GoogleAppsScriptタグがついております。

今日のアジェンダ

  • 達成したいゴール
  • テーブルのオブジェクト化
  • オブジェクトとfor in文

達成したいゴール

スプレッドシートをデータベースとして扱うときは、主キー(primary key) と 見出し行(header) をもつ 「テーブル構造」 が基本です。

とあるテーブルから、必要な値のみを抽出するばあい、みなさんはどのような処理を行いますか? 

セルにQUERY関数などの式を挿入するのも、1つの手段だと思います。(こちらのnoteをオススメします。) https://note.com/kawamura_/n/n38726f528643

これを、GASで操作してみましょう。

オブジェクト化レコーズ

テーブル構造のデータを取得・加工するさい、「列の追加や、列の移動されたらGASが壊れる」という心配があります。

なので、テーブルの見出し行と値がセットになった、オブジェクトに変換して処理を行います。

const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1");
const [header, ...records] = sheet.getDataRange().getValues();

const objectRecords = records.map(record => {
  const obj = {};
  header.forEach((element, index) => obj[element] = record[index]);
  return obj;
});

console.log(objectRecords);
// [ { id: 'tg001', name: 'Tsujike', address: 'Hokkaido' },
// { id: 'tg002', name: 'Takahashi', address: 'Fukuoka' },
// { id: 'tg003', name: 'Etau', address: 'Tokyo' } ]

このような形式を、「オブジェクト化レコーズ」 と呼ぶことにします。

オブジェクトに変換することで、今まで配列のインデックスで指定していた見出し行を、具体的な値(idやnameなど)で指定できます。

列が移動したり、列の増減があっても、GASが壊れることはありません。

//配列のインデックスで指定
console.log(records[0][0]); //tg001
console.log(records[2][2]); //Tokyo

//オブジェクト化
console.log(objectRecords[0]["id"]); //tg001
console.log(objectRecords[2]["address"]); //Tokyo

さまざまな加工処理を行ったあとは、再び2次元配列に戻して、スプレッドシートに貼り付けたりします。

const undoObjectRecords = objectRecords.map(record => Object.values(record));
console.log(undoObjectRecords);
// [ [ 'tg001', 'Tsujike', 'Hokkaido' ],
// [ 'tg002', 'Takahashi', 'Fukuoka' ],
// [ 'tg003', 'Etau', 'Tokyo' ] ]

ぜひ、スニペット化しましょう。

オブジェクトとfor in文

for in文は、オブジェクトのプロパティを捜査するループ処理です。

しかし、見かけの順序通りの取り出しが補償されていなかったり、プロトタイプチェーンを遡ったり、バグを生む原因になることもあります。

const member = { id: 1, name: "Tsujike", address: "Hokkaido" };
member.__proto__.property = "";

console.log(member); //{ id: 1, name: 'Tsujike', address: 'Hokkaido' }

for (const value in member) {
  console.log(value); //id, name, address, property
}

このため、多くのプログラマは、for/inループではなく、Object.keys()を使ってfor/ofループを利用するようになっています。(脚注1)

Objectクラスの便利なメソッドたち

GASのObjectクラスでは、オブジェクトのプロパティ(GASではkeyと呼んでいます)や値を取得するメソッドが、3つ提供されています。

実際に、コードで確認してみましょう。

const member = { id: 1, name: "Tsujike", address: "Hokkaido" };

const keys = Object.keys(member);
console.log(keys); //[ 'id', 'name', 'address' ]

const values = Object.values(member);
console.log(values); //[ 1, 'Tsujike', 'Hokkaido' ]

const element = Object.entries(member);
console.log(element); //[ [ 'id', 1 ], [ 'name', 'Tsujike' ], [ 'address', 'Hokkaido' ] ]

for (const [key, value] ofObject.entries(member)) {
  console.log(`key:${key} と value:${value}`);
}
//key:id と value:1
//key:name と value:Tsujike
//key:address と value:Hokkaido

戻り値はすべて配列というのが、ポイントです。

次回は、この配列を、反復処理しましょう。

まとめ

以上で、「オブジェクトにフィルターをかけて抽出しよう」の「はじめに」をお届けしました。

オブジェクト化レコーズとObjectクラスの3つのメソッドを、ぜひ覚えましょう。

次回は、「反復メソッドによる抽出」をお届けします。

参考文献

GitHubリポジトリ

GitHub - tsujike/-Blog-ObjectFilter: [オブジェクトにフィルターをかけて抽出しよう
[オブジェクトにフィルターをかけて抽出しよう. Contribute to tsujike/-Blog-ObjectFilter development by creating an account on GitHub.

このシリーズの目次

タイトルとURLをコピーしました