【ITニュース解説】How to Generate Product Variant Permutations in Vanilla JavaScript
2025年09月20日に「Dev.to」が公開したITニュース「How to Generate Product Variant Permutations in Vanilla JavaScript」について初心者にもわかりやすく解説しています。
ITニュース概要
ECサイトでTシャツのサイズや色など、多数の商品の組み合わせを自動生成する方法を解説。Vanilla JavaScriptを使い、選択肢から可能なバリエーションをリアルタイムで表示するコンポーネントの構築手順を紹介する。`map`や`reduce`で効率的に組み合わせを計算する。
ITニュース解説
ECサイトで商品を探す際、Tシャツには4つのサイズ、5つの色、3つのスタイルといったように、多くの選択肢があることに気づく。これらの選択肢を組み合わせると、膨大な数の商品バリエーションが生まれる。もし、これら全ての組み合わせを一つずつ手作業でリストアップしようとすれば、それは非常に困難で、間違いも発生しやすくなるだろう。この記事では、このような複雑な問題を、JavaScriptというプログラミング言語を使って自動的に解決する方法について解説する。ユーザーが選択肢を選んだ際に、リアルタイムで可能な組み合わせが更新されて表示される、インタラクティブな機能の構築を目指す。
まず、ウェブページの基本的な構造であるHTMLを用意する。permutations.htmlという名前のファイルで、ウェブページの骨組みを定義する。この中には、ユーザーがサイズや色といったオプションを選択するためのエリアと、その選択に基づいて生成された組み合わせ結果を表示するためのエリアという、主に二つのdiv要素が準備される。スタイルを適用するためにTailwind CSSというフレームワークが使用され、構築する機能を制御するためのJavaScriptファイル(permutations.js)は、ウェブページが読み込まれたときにtype="module"として読み込まれる。このtype="module"は、JavaScriptをモジュールとして扱うことで、他のスクリプトとの干渉を防ぎ、より現代的な開発手法を可能にする。
次に、JavaScriptのコードに移り、商品オプションのデータをどのように扱うかを決める。permutations.jsファイル内でoptionsDataという名前の定数配列を定義する。この配列の各要素は、商品のオプションカテゴリ(例:「サイズ」「色」「柄」)を表すオブジェクトである。それぞれのオブジェクトには、カテゴリの名前(name)と、そのカテゴリ内の具体的な選択肢(variants)を格納する配列が含まれる。さらに、各バリアントのオブジェクトには、表示用のラベル(label)、実際の値(value)、そしてそのバリアントが現在選択されているかどうかを示す真偽値(checked)のプロパティがある。このデータ構造を採用することで、様々な種類のオプションを柔軟に管理し、拡張しやすい基盤を構築できる。checkedプロパティは、初期状態でどのオプションが選択されているかを設定したり、ユーザーの操作に応じて状態を更新したりするために非常に重要である。
このシステムの核心となるのは、選択されたオプションから全ての可能な組み合わせを生成するロジック、つまりcalculatePermutations()関数である。この関数は二つの主要なステップで構成される。
ステップ1では、optionsDataから現在選択されているバリアント、つまりcheckedプロパティがtrueになっているバリアントだけを抽出する。これにはJavaScriptのmapとfilterというメソッドが使われる。まずmapを使って各オプションカテゴリから選択されたバリアントのvalueだけを取り出し、次にfilterを使って、選択されたバリアントが一つもなかったカテゴリの空の配列を除外する。例えば、「Small」「Medium」「Blue」「Plain」が選択されていた場合、activeVariantsという変数には[['Small', 'Medium'], ['Blue'], ['Plain']]のような二次元配列が格納される。これは、各内部配列がそれぞれ異なるオプションカテゴリ(サイズ、色、柄)における選択肢を表している。
ステップ2では、このactiveVariants配列を使って、reduceメソッドにより全ての組み合わせを生成する。reduceは配列の各要素を順番に処理し、一つの最終的な値(ここでは全ての組み合わせを含む配列)に集約する強力なメソッドである。reduceメソッドは、現在の集約結果である「アキュムレータ(acc)」と、現在処理している要素である「カレント(current)」の二つを引数に取るコールバック関数を繰り返し実行する。
最初の呼び出しでは、accは空の配列([])として初期化され、currentにはactiveVariantsの最初の要素、例えば['Small', 'Medium']が渡される。このとき、accが空なので、currentの各要素をそれぞれ単一の要素を持つ配列に変換し、[['Small'], ['Medium']]がaccとして返される。
次に、accは[['Small'], ['Medium']]となり、currentにはactiveVariantsの二番目の要素、例えば['Blue']が渡される。この段階では、newCombinationsという新しい配列が用意され、既存のaccの各要素(['Small']と['Medium'])それぞれに対して、currentの各要素(['Blue'])を結合する処理が行われる。結果として、['Small', 'Blue']と['Medium', 'Blue']という新しい組み合わせが生成され、newCombinationsに格納される。このnewCombinationsが次のaccとなる。
さらに、accは[['Small', 'Blue'], ['Medium', 'Blue']]となり、currentにはactiveVariantsの三番目の要素、例えば['Plain']が渡される。同様の結合処理が繰り返され、最終的に[['Small', 'Blue', 'Plain'], ['Medium', 'Blue', 'Plain']]という全ての組み合わせが生成され、calculatePermutations()関数の結果として返される。
ロジックが完成したら、ユーザーがシステムと対話できるように、ユーザーインターフェース(UI)を操作する関数を実装する。
renderOptions()関数は、optionsDataの内容に基づいて、HTML上のoptions-container内にチェックボックスやそれに関連するラベルを動的に生成する。この関数が呼び出されるたびに、以前のコンテンツは一度クリアされ、最新のデータに基づいてUIが再描画される。各チェックボックスが生成される際、そこにはchangeイベントリスナーが追加される。このイベントリスナーは、ユーザーがチェックボックスの状態(チェックを入れる、外す)を変更したときに動作する。イベントが発火すると、そのチェックボックスの新しい状態がoptionsData内の該当するバリアントのcheckedプロパティに反映され、データが更新される。その後、renderOptions()関数自身とcalculatePermutations()関数が再度呼び出される。これにより、UIがすぐに更新され、同時に新しい選択状態に基づいた組み合わせが再計算されるため、ユーザーはリアルタイムで変化を確認できる。
最後に、renderResults()関数は、calculatePermutations()によって生成された組み合わせの配列を受け取り、それをHTML上のresults-container内に、見やすいリスト形式で表示する役割を担う。各組み合わせは、例えば「Small / Blue / Plain」のようにスラッシュで区切られたテキストとして整形され、リストの項目として追加される。これにより、ユーザーは生成された全ての組み合わせを一目で確認できるようになる。
このように、HTMLでの基本的な構造定義、JavaScriptでの柔軟なデータ構造設計、そしてmap、filter、reduceといった強力な配列メソッドを組み合わせたコアロジック、さらにユーザーの操作に応じてデータとUIをリアルタイムで同期させるイベント処理を統合することで、複雑な商品バリエーションの組み合わせ生成という実世界の課題を、簡潔でインタラクティブな方法で解決できるシステムが構築される。これは、システムエンジニアを目指す上で、データとロジック、そしてUIを結びつける基本的な考え方を示す良い例である。