【GAS】配列の宣言・初期化・頻出メソッド
Google Apps Script(GAS)では、効率の良いスクリプトを書くために配列がとても重要な役割を果たします。この記事では、配列の宣言・初期化方法から、配列を扱ううえで頻出する重要メソッド、配列の扱い方についてご紹介します。
GASの配列とは
「配列」とは変数の一つで「配列変数」とも言い、2つ以上の複数の値を保持できます。
// 多くの変数は1つの値のみを保持
let string = 'apple';
let int = 10;
let boolean = true;
// 配列は複数の値を保持できる
let array = ['apple', 'orange', 'grape'];
インデックスによる位置指定
複数の文字列や数値を保持し、それぞれを配列内の通し番号(「インデックス」と呼ばれます)で扱うことができます。このインデックスを用いて配列内の位置を指定してデータを処理できるのが配列の便利なところです。
let animals = ['dog', 'cat', 'tiger'];
//インデックスを指定して呼び出し
console.log(animals[0]);//dog
console.log(animals[1]);//cat
console.log(animals[2]);//tiger
console.log(animals[3]);//undefined ※インデックス「3」に該当する値はanilmalsでは定義されていない
GASの処理では配列は頻出
GASではGoogleサービス、特にスプレッドシートから値を取得したり挿入したりして扱うことが多いです。スプレッドシートからデータを取得したり挿入する際に、セルを一つずつ処理するのはかなり手間ですし冗長になります。
配列を用いて、スプレッドシートシートの行×列を表現できるとこの処理が分かりやすく、簡単になります。GASを扱ううえで配列の取り扱いは必須だと思ってぜひマスターしましょう。
配列を用いてスプレッドシートでどのような処理ができるかは下記の記事を見てみてください。
配列の宣言・代入・初期化
それでは基本的な操作を見ていきましょう。
配列の宣言・初期化
配列の宣言は、配列リテラルの形で記述するか、初期化記号「new」と共にに配列を表す「Array」で初期化するという2通りの方法があります。
前者については最初から値を格納することも可能です。その場合は角括弧([])の中で各要素をカンマ(,)で分ける形になります。
Array= [] または Array=[要素1, 要素2, 要素3, 要素4, …]
let array = [];
console.log(array); //[]
let array = ['apple', 'orange', 'grape'];
console.log(array); //['apple', 'orange', 'grape']
new Array()
let array = new Array();
console.log(array); //[]
配列要素の代入
Array[インデックス番号]
配列内の各要素を『Array[インデックス番号]』の形で記述して代入します。言語全般と同様ですが、配列のインデックス番号は「0」から始まります。
let array = ['apple', 'orange', 'grape'];
console.log(array); //[ 'apple', 'orange', 'grape' ]
array[0] = 'banana';
console.log(array); //[ 'banana', 'orange', 'grape' ]
途中のインデックスを飛ばして代入することも可能
arrayという配列に3つの要素しか入っていない場合でも、例えばarray[5]に要素を追加することも可能です。その場合は飛ばされたarray[3]とarray[4]にはnullが格納されます。
let array = ['apple', 'orange', 'grape'];
array[5] = 'peach';
console.log(array); //[ 'apple', 'orange', 'grape', , , 'peach' ]
constで宣言しても要素は再代入できる
定数で宣言されている配列もその要素であれば再代入可能です。ただし、配列を再代入しようとするとエラーになります。
const array = ['apple', 'orange', 'grape'];
//配列要素に代入はOK
array[0] = 'banana';
console.log(array); //[ 'banana', 'orange', 'grape']
//配列そのものを代入しようとするとエラーとなる
array = [ 'banana', 'orange', 'grape'] //TypeError: Assignment to constant variable.
配列の分割代入
複数の変数や定数をまとめて宣言・代入したいときは、配列を使った分割代入が非常に便利です。どちらも宣言と代入を一度に行うことができ、変数であれば先に宣言だけしておき後から分割代入することも可能です。
let [str, num, array]= ['happy', 25, ['Bob','Mike']];
console.log(str); //happy
console.log(num); //25
console.log(array); //[ 'Bob', 'Mike' ]
配列の要素の展開・スプレッド構文
ある配列を展開したいときは、スプレッド構文を使います。ドット記号(.)を3つ並べた後に配列を記述します。
…Array
例えば、この一文で二次元配列を一次元列に変換できます。スプレッドシートから取得したデータは1列のデータだったとしても二次元配列になっており、この構文で展開するとシンプルな処理にできたりするので便利です。
let array = [['apple', 'orange', 'grape']];
console.log(...array);//[ 'apple', 'orange', 'grape' ]
下記のように展開したうえでそのまま配列に格納するといったことも可能です。
let array = ['apple', 'orange', 'grape'];
console.log(['banana', ...array, 'peach']) // [ 'banana', 'apple', 'orange', 'grape', 'peach' ]
配列の種類:二次元配列と連想配列
二次元配列
配列は単一の値だけではなく要素を複数持つ配列も要素として格納することが可能です。角括弧([])で囲った変数の要素の中に、二重に角括弧([])を使用して定義できます。このような配列が二重に入れ子になっている構造の配列を二次元配列と呼びます。
[[要素1, 要素2], [要素3, 要素4], …]
let array = [['apple', 'grape'], ['cokkie','bred']];
console.log(array); //[['apple', 'grape'] , [ 'cokkie', 'bred' ] ]
また一次元配列と同様にインデックス番号で指定することで参照と代入が可能です。2層下の要素を一度に参照する際は、『Array[1][[1]』のように各次元でインデックス番号を指定します。
console.log(array); // [['apple', 'grape'] , [ 'cokkie', 'bred' ] ]
console.log(array[0]); // ['apple', 'grape']
console.log(array[1][1]); // 'bred'
array[0] = ['tomato'];
console.log(array); // [['tomato'] , ['cokkie','bred']]
array[2] = ['wine','beer'];
console.log(array); // [['tomato'] , ['cokkie','bred'] , ['wine','beer']]
ちなみに三次元以上の配列も同様に定義・抽出できますが、多次元の配列処理は複雑になりすぎてしまうのと、スプレッドシートと連携した処理が多いGASでは二次元配列の処理をマスターしておけば多くの場合問題ないでしょう。
連想配列
{名前1 : 値1 , 名前2 : 値2, …}
名前(キー)と値(バリュー)が1対1で対応するように定義づけられた配列できます。[:](コロン)を挟んで名前と値を対応させ波括弧({})で囲んで宣言します。
下記図のように名前のついた複数の箱の中に値が入っているイメージのデータ構造で、この箱の名前を使って参照や代入を行えるので可読性が高いデータとなっています。
let array_1 = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3'
};
console.log(array_1); //{ key1: 'value1', key2: 'value2', key3: 'value3' }
参照・代入する方法は下記の2つがあります。
ブラケット記法:連想配列.['名前’]
ドット記法:連想配列.名前
//ブラケット記法
let array_2 = {};
array_2['key1'] = 'value1';
array_2['key2'] = 'value2';
array_2['key3'] = 'value3';
console.log(array_2); //{ key1: 'value1', key2: 'value2', key3: 'value3' }
console.log(array_2['key1']); //value1
//ドット記法
let array_3 = {};
array_3.key1 = 'value1';
array_3.key2 = 'value2';
array_3.key3 = 'value3';
console.log(array_3); //{ key1: 'value1', key2: 'value2', key3: 'value3' }
console.log(array_3['key1']); //value1
ちなみに2次元配列と連想配列は互いに変換可能です。スプレッドシートからデータを読み込んだ時点では二次元配列だが処理の都合上で連想配列にしたい、といったこともあるのでそれぞれの活用シーンの違いや変換方法を覚えておきましょう。
スプレッドシートからの読み込み
スプレッドシートのデータを二次元配列として取得します。
//対象シートのデータをすべて読み込む
let sheet = SpreadsheetApp.getActiveSheet();
let values = sheet.getDataRange().getValues();
console.log(values);
/*
[ [ '店舗名', '売上', '売上個数' ],
[ 'A', 265372, 204 ],
[ 'B', 265427, 221 ],
[ 'C', 331522, 301 ],
[ 'D', 110193, 138 ] ]
*/
行単位の配列を要素とする二次元配列として抽出できました。
スプレッドシートへの書き込み
値を特定のセルに書き込む(setValue)
Range.setValue(値)
setValueメソッドは単一の値を一つのセルに書き込むメソッドです。Rangeオブジェクトが特定のセルを指定していればそのセルに、指定していなければ'A1’セルに書き込まれます。
let ss = SpreadsheetApp.getActiveSpreadsheet(); //書き込み先のスプレッドシートファイル
let sheet = ss.getActiveSheet(); //書き込み先のシート
let range_1 = sheet.getRange('A1'); //書き込み先の範囲
range_1.setValue('テスト'); // 引数の値をセルに入力
let range_2 = sheet.getRange('C3'); //書き込み先の範囲
range_2.setValue('テスト'); // 引数の値をセルに入力
二次元配列を複数のセルに書き込む
Range.setValues(配列)
setValuesメソッドは配列を引数として複数のセルに値を書き込むメソッドです。Rangeオブジェクトは配列と同じ行×列数を指定している必要があり、一致しないとエラーになります。下記では5行×4列(行:1~5、列:A~D)の配列を書き込きます。
let ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName('テスト');
let range = sheet.getRange('A1:D5');
let sales = [
[ '商品', '価格', '個数', '売上' ],
[ 'ハンバーグ', 1000, 12, 12000 ],
[ 'スープ', 500, 18, 9000 ],
[ 'カレー', 1500, 8, 12000 ],
[ 'シチュー', 800, 18, 14400 ] ]
range.setValues(sales);
一次元配列をデータの最終行に書き込む(appendRow)
Sheet.appendRow(rowContents)
- rowContents:シート最終行へ挿入する一次元配列
//書き込みたい対象のシート
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
//追加用の一次元配列
let addSales = [ 'スパゲッティ', 1000, 4, 4000 ];
//最終行にデータを追加
sheet.appendRow(addSales);
2行以上書き込む場合はappendRowメソッドは回数分逐次で実行します。
配列の長さを取得
Array.length
配列の長さ(要素数)を取り出したい場合は『配列.length』と記述します。
let array = ['apple', 'orange', 'grape'];
console.log(array.length);//3
「配列の要素数はわからないけど最後の要素が知りたい」場合は、『配列[配列.length-1]』と記述できます。
console.log(array[array.length-1]); //grape
配列の要素追加・削除
配列に要素追加、または要素の削除を実施する場合、下記の代表的なメソッドを使うことが多いです。
- shiftメソッド:最初の要素を抽出
- unshiftメソッド:先頭に新しい要素を追加
- pushメソッド:末尾に新しい要素を追加
- popメソッド:最後の要素を抽出
- spliceメソッド:任意の要素の削除と追加
shiftメソッド:最初の要素を抽出
Array.shift()
配列の最初の要素を取り除き、取り除いた要素を返すメソッドです。
let array = ['apple', 'orange', 'grape'];
let arrayShift = array.shift();
console.log(array); //[ 'orange', 'grape' ]
console.log(arrayShift); //apple
consoleでも確認できるように、shiftメソッド発動後は元の配列の形が変化します。
unshiftメソッド:先頭に新しい要素を追加
Array.unshift(<追加したい要素>)
shiftメソッドと異なり、配列に格納したい要素と一緒に.unshift(<追加したい要素>) の形で使います。
配列の最初に要素を追加し、追加後の新しい配列の長さを返します。
let array = ['apple', 'orange', 'grape'];
let arrayUnshift = array.unshift('peach');
console.log(array); //[ 'peach', 'apple', 'orange', 'grape' ]
console.log(arrayUnshift); //4
pushメソッド:末尾に新しい要素を追加
Array.push(<追加したい要素>)
配列の末尾に新しい要素を追加しします。unshiftと同様.push(<追加したい要素>) の形で使い、新しい配列の長さを返します。
let array = ['apple', 'orange', 'grape'];
let arrayPush = array.push('peach');
console.log(array); //[ 'apple', 'orange', 'grape', 'peach' ]
console.log(arrayPush); //4
popメソッド:最後の要素を抽出
Array.pop()
配列の最後の要素を取り除き、取り除いた要素を返します。
shiftが先頭の要素を取り除くのに対し、こちらは最後の要素を取り除く関数です。
let array = ['apple', 'orange', 'grape'];
let arrayPop = array.pop();
console.log(array); //[ 'apple', 'orange' ]
console.log(arrayPop); //grape
spliceメソッド:任意の要素の削除と追加
Array.splice(配列番号, 削除する要素数, 追加する要素1, 追加する要素2, …)
配列の特定位置にある要素を取り除き、新しい要素を追加できます。
要は、配列内の好きな場所の要素を削除、新しく要素を追加する事ができる超使い勝手が良いメソッドです。
let array = ['apple', 'orange', 'grape'];
let arraySplice = array.splice(1,1,"banana");
//配列番号「1」(orange)から数えて1つの要素を削除し、"banana"を追加する
console.log(array); //[ 'apple', 'banana', 'grape' ]
console.log(arrayPush); //[ 'orange' ]
ちなみに、削除する要素数と追加する要素数は一致している必要はなく、元々の配列から2つ削除して、追加する要素数は1つのみだったり、逆に1つの要素を削除して2つの要素を追加することも可能です。
配列の結合
配列の要素同士の結合、配列同士の結合について解説します。
複数の一次元配列を結合して一次元配列をつくる
一番シンプルで使う頻度が多い配列の結合方法は、一次元配列同士を連結して新たな一次元配列をつくるパターンでしょう。concatメソッドを利用することで元の配列を縦結合して新たな配列をつくることができます。
Array1.concat(Array2 [, Array3] )
let array1 = ['apple', 'orange', 'grape'];
let array2 = ['candy', 'cookie'];
let array3 = array1.concat(array2);
console.log(array3); // [ 'apple', 'orange', 'grape', 'candy', 'cookie' ]
3つ以上の配列もカンマ(,)で区切ることで、concatメソッドを使うことで同様に結合できます。
let array1 = ['apple', 'orange', 'grape'];
let array2 = ['candy', 'cookie'];
let array3 = ['tomato', 'cabbage'];
let array4 = array1.concat(array2,array3);
console.log(array4); //[ 'apple', 'orange', 'grape', 'candy', 'cookie', 'tomato', 'cabbage' ]
複数の一次元配列を結合して二次元配列をつくる
配列同士を配列のまま結合して二次元配列を作成する方法です。いくつか手法がありますが、空配列を先に作っておき、pushメソッドで結合する方法が最もシンプルで簡単かと思います。
[Array1, Array2 [, Array3]]
let array1 = ['apple', 'orange', 'grape'];
let array2 = ['candy', 'cookie'];
let array3 = [array1, array2];
console.log(array3);//[ [ 'apple', 'orange', 'grape' ], [ 'candy', 'cookie' ] ]
concatメソッド同様に、カンマ(,)で区切ることで3つ以上の配列を結合することも可能です。
一つの一次元配列の要素同士を結合する
joinメソッドを使うことで配列内の文字列を結合できます。
Array.join([sep])
- sep(任意):要素結合の際に結合部分に挿入される文字列
let array1 = ['apple', 'orange', 'grape'];
console.log(array1.join('-')); // apple-orange-grape
複数の一次元配列の要素同士を結合する
同じ要素数を持つ2つ以上の配列の要素同士を結合したい場合もあるでしょう。特定メソッドは用意されていないので、繰り返し文で1行ずつ要素同士を結合する処理を実行します。
let array1 = ['apple', 'orange', 'grape'];
let array2 = ['candy', 'cookie', 'chocolate'];
let array3 = [];
for(let i=0; i <array1.length; i++){
arrayC.push(array1[i]+ '-' +array2[i]);
}
console.log(array3);//[ 'apple-candy', 'orange-cookie', 'grape-chocolate' ]
発展ですが、二次元配列の結合も覚えておくと便利でしょう。
配列内に特定文字列が含まれているかの検索
配列内の要素を検索する方法はいくつかありますが、代表的なものはindexOfメソッドです。
Array.indexOf(string[,from])
- Array:指定文字列が含まれているかを検索したい対象の配列オブジェクト
- string(必須):検索条件となる文字列
- from(任意):検索を始める場所の指定、indexOfは先頭から、lastIndexOfは最後尾から数える
- 戻り値:マッチした位置(インデックス番号)、マッチしない場合は「-1」
let arrayA = [ 'apple', 'orange', 'grape', 'candy', 'cookie' ];
console.log(arrayA.indexOf('orange')); //1
注意点として、indexOfメソッドは配列の先頭から検索していくため検索値に最初に合致する要素のインデックス番号しか取得できません。配列の要素の中に複数同じ値が含まれている場合は、先頭から最も近い要素のインデックス番号が取得されます。
他にもいくつか文字列を検索する方法があるので確認してみてください!
まとめ
Google Apps Script(GAS)で配列の定義と種類、追加と削除に使えるメソッド、スプレッドシートから読み込みと書き込み方法などを解説しました。ぜひいろいろなシーンで活用してみてください!