GAS初心者がfor文やif文の次に学ぶと急激にレベルアップする技術7選

  • このエントリーをはてなブックマークに追加
  • LINEで送る

0.はじめに

GAS初心者の方々、こんな悩みはありませんでしょうか。

「次に何を学べばいいのか分からない」
「とりあえずforとifで色々できるようになったけど、ネストだらけ・・・」

そんな方々へ、次の1歩として覚えると非常に便利になり
またコードを書くのがずっと簡単に、楽しくなる技術を紹介します。

1.for in

まずはfor inです。先にサンプルをどうぞ。

function myFunction() {
  const test = [0,1,2,3,4,5,6,7,8];

  //これをループする時、一番最初に学ぶfor文ではこう書きます。
  for(let i = 0; i<test.length; i++){
    console.log(test[i]);
  }

  //for inを使うと、こうなります。
  for(let i in test){
    console.log(test[i]);
  }
}

MDNリファレンス for-in

はい、短くなりましたね!
配列をループする時、配列の最初から最後までのインデックスを加算しつつループしてくれます。
長ったらしいfor文を書くよりスッキリして楽に書けてGoodです。

2.for of

続いてfor ofです。私も非常によく使います。


function myFunction() {
  const items = [0,1,2,3,4,5,6,7,8];

  //これをループする時、一番最初に学ぶfor文ではこう書きます。
  for(let i = 0; i<items.length; i++){
    console.log(items[i]);
  }

  //for ofを使うと、こうなります。
  for(let item of items){
    console.log(item);
  }
}

MDNリファレンス – for of

はい。お分かり頂けましたでしょうか?
for of文は、インデックスナンバーをループするわけではなく
配列内の中身を順番に取り出してくれます。

for inとの使い分けですが、

処理中にインデックスナンバーが必要な場合はfor in、
配列の中身だけが必要な場合はfor of

という風に考えるとよいでしょう。

実際にコピペして動かしてみると実感がわきますよ。

3.連想配列

これはプログラミングを深めるに当たっては避けて通れない技術です。
次項からの内容と絡めると大いに役立つので、ぜひ理解してください。

function myFunction() {
  let player = {name:"田中", age:20, team:"腹八分目"};

  console.log(player.name); //田中が出力される
  console.log(player.team); //腹八分目が出力される

  //チームを移籍したら・・・これで変更できる。
  player.team = "満腹党";
  console.log(player.team); //満腹党が出力される
}

これだけだと「何のためにあるの?」と思うかもしれません。すいません。

playerについて氏名や年齢の他にも、所属履歴や家族構成、緊急連絡先、身体測定の結果などを管理したい場合、
普通の配列だと「index12番目は家族構成で・・・」と、かなり運用に難が出ます。
そんな時、連想配列を使うと簡単に目的のデータに辿り着く事ができます。

4.JSON形式

ジェイソンと呼びます。嘘じゃないです。
何となく専門的な雰囲気がありますが、配列みたいなもんです。難しく考えないでください。


function myFunction() {
  let players = [
                  {name:"田中", age:25, team:"腹八分目", mail:"tanaka@harahachi_test.co.jp"},
                  {name:"田村", age:20, team:"腹八分目", mail:"tamura@harahachi_test.co.jp"},
                  {name:"田村中", age:23, team:"満腹党", mail:"tamuranaka@manpuku_test.co.jp"}
                ];

  //普通の配列と同じようにpushできる。
  players.push({name:"田井中", age:26, team:"満腹党", mail:"tainaka@manpuku_test.co.jp"});

  for(let player of players){
    console.log(player.mail);
    //1人ずつ順番にメールを送る処理などができる。
  }
}

前項では1名分しか管理しなかった内容について複数のデータをplayersという1つの変数で管理できます。
また配列にいくつかのデータが入っているようなものなので、ループも回せます。

例えばスプレッドシートに管理している数十人のデータを取得してJSON形式にしたら、
この例のように実務でも扱いやすそうなイメージが湧いてきませんか?

5.filter

ここからが本番です!
filterとの文字通り、配列の中身をフィルタリングします。

function myFunction(){
  //例1
  const numbers = [0,55,23,45,899,6443,23,456,47];
  const under100 = numbers.filter(num => num<100);
  console.log(under100);
  //[ 0, 55, 23, 45, 23, 47 ]が出力される

  //例2
  const players = [
                  {name:"田中", age:25, team:"腹八分目", mail:"tanaka@harahachi_test.co.jp"},
                  {name:"田村", age:20, team:"腹八分目", mail:"tamura@harahachi_test.co.jp"},
                  {name:"田村中", age:23, team:"満腹党", mail:"tamuranaka@manpuku_test.co.jp"},
                  {name:"田井中", age:26, team:"満腹党", mail:"tainaka@manpuku_test.co.jp"}
                ];
  const team8 = players.filter(player => player.team == "腹八分目");
  console.log(team8);
  /**
  [ { name: '田中', age: 25, team: '腹八分目', mail: 'tanaka@harahachi_test.co.jp' },
    { name: '田村', age: 20, team: '腹八分目', mail: 'tamura@harahachi_test.co.jp' } ]
  が出力される。
   */

  //その後の活用例
  for(let player of team8){
    let mail = player.mail;
    //teamが腹八分目のメンバーだけにメールを送ったりできる!
  }
}

MDNリファレンス – filter

イメージ頂きやすいように書きましたが、サンプルを見るだけで理解できたら凄いです。

例1は、数字配列を100未満のものだけにフィルタしています。
filter(num => num<100)の部分ですが、numの中に配列の中身が順番に入って
100未満かどうかを確かめている、という風に理解してください。
for ofに100未満という条件が付いた感じに近いかもしれません。

例2ではJSON形式に対して実行してみました。これも業務で非常によく使うパターンです。
もし練習したい場合、25歳以上の人だけを取り出してconsole.logで確認してみてください!

6.find

filterを理解できた方、素晴らしいです。
findも非常に似ていますので、似た感覚で見てください。

function myFunction(){
  const players = [
                  {name:"田中", age:25, team:"腹八分目", mail:"tanaka@harahachi_test.co.jp"},
                  {name:"田村", age:20, team:"腹八分目", mail:"tamura@harahachi_test.co.jp"},
                  {name:"田村中", age:20, team:"満腹党", mail:"tamuranaka@manpuku_test.co.jp"},
                  {name:"田井中", age:26, team:"満腹党", mail:"tainaka@manpuku_test.co.jp"}
                ];
  const team8 = players.find(player => player.age == 20);
  console.log(team8);
  //  {name:"田村", age:20, team:"腹八分目", mail:"tamura@harahachi_test.co.jp"}が出力される。
}

MDNリファレンス – find

age==20のメンバーは2人いるのに1人しか出力されない点に注目してください。
filterでは、条件に一致した時点でそれを返す、という事が行われます。
ですのでfilterと違って、1つしか値が返ってきません。

これだけだと「filterでよくない?何に使うの?」と思う方も多いかもしれません。
個人的には、次の次の項で紹介する複合的な用途でかなり使います。

7.map

filter,findと似た文法でも処理内容は全く異なる超便利メソッド、mapです。
配列の中身を一定の内容に応じて操作し別の変数に格納します。


function myFunction(){
  //例1
  const numbers = [1,2,3,4,5,6,7,8,9];
  const numbers3 = numbers.map(x => x*3);
  console.log(numbers3);
  //	[ 3, 6, 9, 12, 15, 18, 21, 24, 27 ] が出力される

  
  //例2
  const players = [
                  {name:"田中", age:25, team:"腹八分目", mail:"tanaka@harahachi_test.co.jp"},
                  {name:"田村", age:20, team:"腹八分目", mail:"tamura@harahachi_test.co.jp"},
                  {name:"田村中", age:20, team:"満腹党", mail:"tamuranaka@manpuku_test.co.jp"},
                  {name:"田井中", age:26, team:"満腹党", mail:"tainaka@manpuku_test.co.jp"}
                ];

  //名前だけの配列を作りたい場合
  const names = players.map(x => x.name);
  console.log(names);
  //	[ '田中', '田村', '田村中', '田井中' ] が出力される

}

MDNリファレンス – map

例1では配列の各要素に対して3倍した配列が生成されています。
例2ではname属性の中身だけの配列が生成されています。

配列の各要素に対して処理を行った結果を配列として返す、という技術になります。

練習したい場合、
例1ではnumbersの各要素に対して10足した配列を作成、
例2ではplayersのmailだけの配列を作成してみてください。

8.複合技

集大成です。今までの内容を複雑に組み合わせた例を作ってみました。
少々理解に手間取るかもしれません。私自身も最初は脳ミソ爆発しそうでした。


function myFunction(){
  //スプレッドシート1から取得したプレイヤー情報
  const players = [
                  {id:0001 ,name:"田中", age:25},
                  {id:0002, name:"田村", age:20},
                  {id:0003, name:"田村中", age:20},
                  {id:0004, name:"田井中", age:26},
                  {id:0123, name:"田牧", age:32},
                  {id:0222, name:"田中", age:26},
                  {id:0333, name:"田坂", age:16}
                ];

  //スプレッドシート2から取得したチーム1のメンバーIDリスト
  const team1Master = [0003,0005,0222];

  //上記の2つを用いて、playersを元にチーム1のメンバー配列を作りたい
  const team1Players = players.filter(x => team1Master.find(y => y == x.id));
  
  console.log(team1Players);
  /**
  [ { id: 3, name: '田村中', age: 20 },
    { id: 146, name: '田中', age: 26 } ]
  が出力される。
   */
}

あちこちにデータがありマスタ情報と紐づけて必要な情報を生成する際にかなり使います。
業務上、散らかったデータを集めてどうにかするシーンって結構ありますよね。

今回の例ではplayersの1人ずつについて順番に検証し、
team1Masterの中でIDを検索して見つかった人、のみにフィルタした形です。

9.注意点

for文やif文だけでも書こうと思えば書けますが、これらの技術を使うと楽に書けます。
ただ、1つだけ注意点もあります。

8で紹介した複合技ですが、やり過ぎると非常に分かりにくいコードになります。
業務で実際に一度、filterやfind、mapを連結させて50行以上にしてしまった事があります。

確かにそれでも一気に書く事ができますし、処理途中で使用する変数の数は減ります。
しかし、不具合が起きた時に何がおかしいのか検出するのが困難になります。

なぜならfor文の中にはconsole.logを書けますが、filterの中にconsole.logは書けません。
また途中で変数に一度代入したりステップを踏むことで、不具合発生の段階を切り分け易くなります。

ですので「これはやり過ぎだな」と思ったら、途中で処理を区切ったり
別の関数に分けることを考えてみてください。

10.さいごに

いかがでしたでしょうか。難しかったでしょうか。
難しくても、苦しんで突破するだけの価値のある技術群です。

私も長い間、for文やif文だけでGASを業務活用していましたが、
やはりその頃のコードを見ると非常にムダが多いなと感じます。
ただfilterやmap、特に複合技は最初まったく意味不明で大変でしたが・・・。

また、forやifを多用する書き方から一歩先に進む方法も全然分かっていなかったので、
これらの技術を知った時に苦しみながらも、光明が見えたような感覚もありました。

これらの技術は確実にレベルを上げますし、
GASを発展させwebアプリ化する際のJavaScriptでも非常によく使います。
ぜひ習得してみてくださいね。

  • このエントリーをはてなブックマークに追加
  • LINEで送る

コメントを残す

*