[PR] 本記事にはプロモーションが含まれています。

【TypeScript】「省略されたパース処理」を解きほぐしてデータの変化を理解する

TypeScript

はじめに:今回読み解く「省略されたコード」

  実務で頻繁に登場する、テキストデータをオブジェクト配列に変換する「パース処理」。
 メソッドチェーン(.で繋ぐ記法)を使ったコードは簡潔ですが、初心者には「何がどう省略されてこの形になったのか」「途中のデータがどうなっているのか」がブラックボックスになりがちです。

 まずは、今回読み解く対象となる「省略されたモダンなコード」を見てみましょう。

TypeScript
// 今回解きほぐす対象のコード(省略形)
const users: User[] = data.split("\n")
  .filter(line => line !== "")
  .map(line => {
    const [name, ageString, premiumUserString] = line.split(",");
    return {
      name,
      age: Number(ageString),
      premiumUser: premiumUserString === "1"
    };
  });

1. すべて解きほぐした基本形(手続き型アプローチ)

 先ほどのコードが中で何をやっているのか。処理を「1行ずつ順番に行う」最も基礎的なアプローチ(for...of)に書き直して、手順の番号を振って整理しました。

TypeScript
// 【手順2, 5の一部】最終的な格納先として「空っぽの配列(箱)」を自分で用意する
const users: User[] = [];

// 【手順1】改行による分割(ここだけは全体処理)
const lines = data.split("\n");

// 【手順2】1行ずつ順番に取り出して処理
for (const line of lines) {
  // 【手順3】空行の除外(スキップ)
  if (line === "") {
    continue; 
  }

  // 【手順4】項目ごとの切り出し
  const [name, ageString, premiumUserString] = line.split(",");

  // 【手順5】型変換と組み立て、用意した箱への追加(push)
  users.push({
    name,
    age: Number(ageString),
    premiumUser: premiumUserString === "1"
  });
}

2. 省略されたコードとの対比と、データの変化

 上記の基礎的なコードが、配列メソッド(filtermap)を使うことでどのように省略され、最初のコードに戻るのか。各ステップを通過する際のデータの変化(中身)と合わせて見ていきます。

前提知識: 基本形の const users: User[] = []; にあった : User[] は「ここにはUser配列が入るよ」というただの目印(型定義)です。実際に空の箱を作っていたのは = [] の部分です。map メソッドは「完成した新しい配列(箱)」を自動的に作り出して返してくれるため、自分で空の箱(= [])を用意して push し続ける手間は不要になります。

TypeScript
// 【手順2, 5の一部】mapが新しい配列を作って返すため、空の箱の用意(= [])は省略されます。
const users: User[] = 

  // 【手順1】改行による分割(元の lines = data.split("\n"); に該当)
  data.split("\n")
  // ▼ データの変化(両端の空文字も切り出される)
  // [ "", "uhyo,26,1", "John Smith,17,0", "Mary Sue,14,1", "" ]

  // 【手順3】空行の除外(元の if (line === "") continue; に該当)
  // forループ内の条件分岐を、「条件に合わないものを弾く」filterメソッドに任せます。
  .filter(line => line !== "") 
  // ▼ データの変化(空の行が削ぎ落とされ、有効な行だけが残る)
  // [ "uhyo,26,1", "John Smith,17,0", "Mary Sue,14,1" ]

  // 【手順2, 5】配列への追加とループ(元の forループ と users.push に該当)
  // 1行ずつ変換して新しい配列を作り出す map メソッドに任せます。
  .map(line => {
    // 【手順4】項目ごとの切り出し(基本形と同じ)
    const [name, ageString, premiumUserString] = line.split(",");
    // 例:1行目の推移 `"uhyo,26,1"` → `["uhyo", "26", "1"]`
    
    // 【手順5】型変換と組み立て
    return {
      name, 
      age: Number(ageString), 
      premiumUser: premiumUserString === "1"
    };
  });
  // ▼ データの変化(すべての行がオブジェクトに変換され、新しい配列が完成する)
  // [
  //   { name: "uhyo", age: 26, premiumUser: true },
  //   { name: "John Smith", age: 17, premiumUser: false },
  //   { name: "Mary Sue", age: 14, premiumUser: true }
  // ]

データの出力処理

 省略記法によって美しくパースされ、配列に格納されたデータ(users)は、そのまま後続の処理で活用されます。

TypeScript
for (const user of users) {
  if (user.premiumUser) {
    console.log(`${user.name} (${user.age})はプレミアムユーザーです。`);
  } else {
    console.log(`${user.name} (${user.age})はプレミアムユーザーではありません。`);
  }
}

コメント