🍄

スプレッド構文とレスト構文の違いをマリオで考えてみた

2023/08/31に公開2

学びを備忘録としてまとめます

記念すべき第一弾は
【スプレッド構文】と【レスト構文】の違い
です。

... のやつですね。
両者の違いを”マリオ”で考えたら理解しやすかったので、書き記します 🍄

結論:スプレッド構文とレスト構文の違い

結論として、違いはざっくり以下の感じです。

種類 イメージ
スプレッド構文 広げる
レスト構文 集める

スプレッド構文とレスト構文の表記 (...)は似ていますが、異なる目的と場面で使用されています。

マリオのキャラクターを使って理解してみる

まず、マリオのキャラクターチームがあるとします。

javascript
const marioTeam = ["マリオ", "ルイージ", "ピーチ"];

スプレッド構文 (...)

スプレッド構文は、配列またはオブジェクトを個々の要素やプロパティに「広げる」ために使われます。

例えば、新しいキャラクターをマリオのチームに追加したい場合に、スプレッド構文を使います。

javascript
const marioTeam = ["マリオ", "ルイージ", "ピーチ"];
const newCharacter = "ヨッシー";
const updatedMarioTeam = [...marioTeam, newCharacter];
//...marioTeam = スプレッド構文

console.log(updatedMarioTeam);
// ["マリオ", "ルイージ", "ピーチ", "ヨッシー"]

マリオ・ルイージ・ピーチが、...marioTeamの中に収納されていて、updatedMarioTeamの配列の中で「広げ」られています。

そこにnewCharacterとして、ヨッシーが追加されているということです。
(ヨッシーはゲーム内で強い味方なので、嬉しいですね ↑↑)

レスト構文 (...)

一方で、レスト構文は通常、関数の引数や変数の定義で使われます。

レスト構文を使うと、複数の要素を一つの配列に「集める」ことができます。

分割代入でよく使われます!

例えば、マリオのチームから最初のキャラクターだけを取り出して、残りのキャラクターを別の配列に格納できます。

javascript
const marioTeam = ["マリオ", "ルイージ", "ピーチ"];
const [firstCharacter, ...remainingCharacters] = marioTeam;//分割代入
//...remainingCharacters = レスト構文

console.log(firstCharacter); // "マリオ"
console.log(remainingCharacters); // ["ルイージ", "ピーチ"]

firstCharacterには配列の最初のマリオが格納されて、...remainingCharactersには残りのキャラクターが格納されます。

レスト構文は、分割代入をするときに、配列の残りの部分(...remainingCharacters)を新たな配列として取得するための構文ともいえます。

まとめ

スプレッド構文とレスト構文は ... の表記で似てますが、以下のように違う役割を持っていることがわかりましたね。

種類 イメージ
スプレッド構文 広げる
レスト構文 集める

また理解しにくいことはマリオとか身近なものに置き換えて、楽しく学んでいきたいと思います 🖐️

なにか間違っている部分などあれば、お気軽にコメントいただけると幸いです m(_ _)m

Discussion

nap5nap5

radashのAPI使って似たようなことやってみました。

定義側

import { toggle, first, last, chain } from "radash";

export const createParty = (members: string[]) => (member: string) => {
  return {
    prepend: toggle(members, member, (d) => d, { strategy: "prepend" }),
    append: toggle(members, member, (d) => d, { strategy: "append" }),
  };
};

export const cowboy = (members: string[]) => {
  const [head, ...rest] = members;
  return {
    head,
    rest,
  };
};

export const bebop = (members: string[]) => {
  const head = first(members);
  const rest = toggle(members, head);
  return {
    head,
    rest,
  };
};

export const sprout = (members: string[]) => {
  const head = first(members);
  const tail = last(members);
  const rest = chain(
    (d) => toggle(d, head),
    (d) => toggle(d, tail)
  )(members);
  return {
    head,
    rest,
    tail,
  };
};

使用側

import { test, expect } from "vitest";

import { createParty, cowboy, bebop, sprout } from ".";

test("createParty", () => {
  const inputData = ["マリオ", "ルイージ", "ピーチ"];
  const newJoiner = "ヨッシー";
  const outputData = createParty(inputData)(newJoiner);
  expect(outputData).toStrictEqual({
    append: [...inputData, newJoiner],
    prepend: [newJoiner, ...inputData],
  });
});

test("cowboy", () => {
  const inputData = ["マリオ", "ルイージ", "ピーチ"];
  const newJoiner = "ヨッシー";
  const members = [...inputData, newJoiner];
  const outputData = cowboy(members);
  expect(outputData).toStrictEqual({
    head: "マリオ",
    rest: ["ルイージ", "ピーチ", "ヨッシー"],
  });
});

test("bebop", () => {
  const inputData = ["マリオ", "ルイージ", "ピーチ"];
  const newJoiner = "ヨッシー";
  const members = [...inputData, newJoiner];
  const outputData = bebop(members);
  expect(outputData).toStrictEqual({
    head: "マリオ",
    rest: ["ルイージ", "ピーチ", "ヨッシー"],
  });
});

test("sprout", () => {
  const inputData = ["マリオ", "ルイージ", "ピーチ"];
  const newJoiner = "ヨッシー";
  const members = [...inputData, newJoiner];
  const outputData = sprout(members);
  expect(outputData).toStrictEqual({
    head: "マリオ",
    rest: ["ルイージ", "ピーチ"],
    tail: "ヨッシー",
  });
});

demo code.

https://codesandbox.io/p/sandbox/brave-sea-j7kwsg?file=/src/index.test.ts:1,38

簡単ですが、以上です。

minateruminateru

実際のコード付きで、丁寧なコメントありがとうございます!!
初めてのコメントで、嬉しいです(^^)
まだまだ知識が少ないので、コメントいただいたおかげで、radash初めて知りました。

radashのAPI使って似たようなことができるんですね!
レスト構文、スプレッド構文の具体的なコードいただけて、勉強になります。
この機会に他にも見てみようと思います👀