配列したい([] / Array)
1// JavaScript
2const array = ["a1", "a2", "a3"];
3
4// TypeScript
5const array: string[] = ["a1", "a2", "a3"];
6const array: Array<string> = ["a1", "a2", "a3"];
[]リテラルで配列を初期化できます。
TypeScriptでは、配列の要素の型名も指定する必要があります。
1const array = new Array("a1", "a2", "a3");
new Array()コンストラクターでも配列を初期化できます。
ただし、引数の扱いに注意が必要なため、通常はリテラル記法で記述すれば問題ありません。
2次元配列したい([][])
1// セル用の型を定義
2type Cell = string | number | boolean | Date | null;
3const values: Cell[][] = sheet.getDataRange().getValues();
スプレッドシートにあるデータを取得すると、2次元配列(行x列)として返ってきます。
Cell型を定義することで型安全を保つことができます。
1// ヘッダー(header)とデータ(rows)に分割
2// ヘッダー = 1行目:文字列に変換(Cell[] -> string[])
3// データ = 2行目以降:型はそのまま(Cell[])
4const header = values[0].map(String);
5const rows = values
6 .slice(1)
7 .filter(row => row.some(cell => cell !== null && cell !== ""));
さらに、1行目がヘッダー、2行目以降がデータ領域となっていることが多いです。
ヘッダー(header)とデータ(rows)に分割しておくとよいです。
ヒント
スプレッドシートから取得したデータは Cell[][]型となっています。
ヘッダーに相当する1行目もCell[]になっているため、
上記のサンプルではstring[]に変換しています。
また、データ領域からは、["", ""] や ["", null]、[null, null]のようなどのカラムにも値が入っていない空行を除外しています。
1// 配列として取得
2for (const row of rows) {
3 const col0 = row[0];
4 const col1 = row[1];
5}
6
7// オブジェクトとして取り出す
8// ヘッダー名をキーとして利用
9const data = rows.map(row =>
10 Object.fromEntries(
11 header.map( (key, i) => [key, row[i]] )
12 )
13);
14
15// Mapとして取り出す
16const maps: Map<string, Cell>[] = rows.map(row =>
17 new Map(header.map((key, i) => [key, row[i]]))
18);
データ(rows)をそのまま2次元配列(Cell[][])として扱ってもよいですが、ヘッダー名をキーとしたオブジェクトやMap型に変換すると便利です。
値を追加したい(Array.push)
1// 空の配列を作成し、値を追加する
2const array = new Array();
3array.push("a1");
4array.push("a2");
5array.push("a3");
.pushで配列に値を追加できます。
1// 配列の要素を取得
2console.log(array[0]); // -> a1
3console.log(array[1]); // -> a2
4console.log(array[3]); // -> a3
配列のインデックスを指定して、要素を取得できます。
1array.length; // -> 3
2for (let i = 0; i < array.length; i++ ) {
3 const item = array[i];
4 console.log(item);
5}
.lengthで配列の長さを取得できます。
結合したい(Array.concat)
1const array1 = ["a", "b", "c"];
2const array2 = [1, 2, 3];
3const array3 = ["7", "8", "9"];
4const array4 = array1.concat(array2, array3);
5console.log(array4);
6// -> ["a", "b", "c", 1, 2, 3, "7", "8", "9"];
concatメソッドで配列を連結できます。
複数の配列を連結できます。
1const array5 = [...array1, ...array2];
2console.log(array5);
3// -> ["a", "b", "c", 1, 2, 3];
スプレッド演算子(...配列)でも連結できます。
ループしたい
1// for...ofループ
2for (const item of arrays) {
3 console.log(item);
4}
forEachしたい
1// forEachメソッド
2const newArrays = arrays.forEach(item => {
3 // 処理
4 console.log(item)
5})
mapしたい
1// mapメソッド
2const newArrays = arrays.map(item => {
3 // 処理
4 return 結果;
5})
mapメソッドで配列の要素に対して、同じ処理を適用できます。
1// 平方根を計算したい
2const numbers = [1, 4, 9, 16];
3const sqrtNumbers = numbers.map(Math.sqrt);
4console.log(sqrtNumbers);
5// -> [1, 2, 3, 4];
filterしたい
1// filterメソッド
2const newArrays = arrays.filter(callbackFn);
3
4const newArrays = arrays.filter(item => {
5 // フィルター処理
6 return 条件;
7})
filterメソッドを使って、配列から条件にマッチした要素を抽出できます。
1// 正の数を取得したい
2const numbers = [1, -4, 9, -16];
3const positives = numbers.filter(num => num > 0);
4console.log(positives);
5// -> [1, 9];
reduceしたい
1const newScalar = arrays.reduce(callbackFn, initialValue);
1const numbers = [10, 20, 30, 40];
2const sum = numbers.reduce((left, right) => left + right, 0);
3// step1. 初期値を 0 に設定
4// step2. left=0, right=10 で計算 -> 10
5// step3. left=直前の値, right=20 で計算 -> 30
6// step4. left=直前の値, right=30 で計算 -> 60
7// step5. left=直前の値, right=40 で計算 -> 100
8const average = sum / numbers.length;
9console.log(sum); // -> 100
10console.log(average); // -> 25
flatしたい
1const array1 = [1, 2, [3, 4]];
2const array2 = array1.flat();
3console.log(array2);
4// -> [1, 2, 3, 4];
flatメソッドで配列を平坦化できます。
引数に平坦化の深さを指定できます。
平坦化する際、配列の空要素は削除されます。
最大値・最小値したい(Math.max / Math.min)
1const numbers = [10, 20, 5, 40];
2const max = Math.max(...numbers);
3const min = Math.min(...numbers);
Math.max、Math.minとスプレッド演算子(...配列名)を使って、
最大値、最小値を取得できます。
配列同士の演算したい
1left = [1, 2, 3];
2right = [4, 5, 6];
3const added = left.map((value, index) => value + right[index]);
4const subtracted = left.map((value, index) => value - right[index]);
5const multiplied = left.map((value, index) => value * right[index]);
6const divided = left.map((value, index) => value / right[index]);
7const modulo = left.map((value, index) => value % right[index]);
8const powered = left.map((value, index) => Math.pow(value, right[index]));
配列同士の演算はビルトインされていないので、mapメソッドを使って自分で定義します。
1function addLists(left, right) {
2 if (left.length !== right.length) {
3 throw new Error("Arrays must have the same length.");
4 }
5 return left.map((value, index) => value + right[index]);
6}
それぞれ関数にしておくとよさそうです。
1const arrays = [
2 [1, 2, 3],
3 [4, 5, 6],
4 [7, 8, 9]
5];
6const result = arrays.reduce((left, right) => AddLists(left, right));
7// step1. arrays[0] を初期値として使用
8// step2. left=arrays[0], right=arrays[1] を計算
9// -> [5, 7, 9]
10// step3. left=直前の結果, right=arrays[2] を計算
11// -> [12, 15, 18]
複数の配列を処理する場合reduceメソッドを利用すると簡潔にかけます。