カテゴリ: Ruby 更新日: 2026/02/15

Rubyの範囲×Set応用ガイド!在庫管理とブラックリスト照合のテクニック

範囲×Setの応用:在庫ID帯域の管理・ブラックリスト照合テクニック
範囲×Setの応用:在庫ID帯域の管理・ブラックリスト照合テクニック

先生と生徒の会話形式で理解しよう

生徒

「Rubyで、ある数字の範囲から特定の番号だけを除外して管理したいのですが、良い方法はありますか?」

先生

「それなら『Range(範囲)』と『Set(集合)』を組み合わせるのが最適です。在庫のID管理などにとても役立ちますよ。」

生徒

「在庫管理ですか!難しそうに見えますが、初心者でも作れるのでしょうか?」

先生

「はい、基本的な考え方さえわかれば大丈夫です。ブラックリストにある番号を弾くような便利な仕組みを、一緒に作ってみましょう!」

1. 範囲(Range)と集合(Set)の最強コンビ

1. 範囲(Range)と集合(Set)の最強コンビ
1. 範囲(Range)と集合(Set)の最強コンビ

Rubyには、連続したデータを扱うRange(範囲)と、重複を許さないデータの集まりであるSet(集合)という二つの強力な道具があります。プログラミング未経験の方には、Rangeは「1番から100番までの連続したチケット」、Setは「バラバラだけど誰とも被っていない整理券の束」だと想像してみてください。

これらを組み合わせることで、「1000番から2000番までの在庫があるけれど、そのうち欠番や不良品のIDだけを取り除きたい」といった高度な管理が驚くほど簡単にできるようになります。パソコンを触ったことがない方でも、この「全体から特定の部分を操作する」という感覚を掴むことが、プログラミング上達への第一歩です。まずはそれぞれの特徴を活かした在庫管理の基礎から学んでいきましょう。

2. 在庫IDの「帯域」をRangeで作成する

2. 在庫IDの「帯域」をRangeで作成する
2. 在庫IDの「帯域」をRangeで作成する

在庫管理を行う際、一つ一つのIDを手作業で登録するのは大変です。そこで使うのが Range です。Rubyでは (開始..終了) と書くだけで、その間の数字をすべて含んだ「帯域(たいいき)」を作ることができます。

「帯域」とは、データの広がりや範囲のことを指す難しい言葉ですが、ここでは「IDの番号のまとまり」と考えればOKです。例えば、新しく入荷した100個の商品に1001番から1100番までのIDを割り当てる場面を考えてみましょう。Rubyなら、たった一行でこの100個分の番号を用意できます。


# 1001番から1100番までの範囲(在庫IDの帯域)を作成
stock_range = (1001..1100)

# 最初の番号と最後の番号を確認
puts "開始ID: #{stock_range.first}"
puts "終了ID: #{stock_range.last}"

実行結果は以下の通りです。


開始ID: 1001
終了ID: 1100

3. ブラックリスト(除外リスト)をSetで用意する

3. ブラックリスト(除外リスト)をSetで用意する
3. ブラックリスト(除外リスト)をSetで用意する

次に、在庫の中から「販売してはいけない番号」を管理します。例えば、検品で不合格になったものや、予約済みの番号などです。これを管理するのに最適なのが Set(集合) です。Setを使うには、プログラムの冒頭に必ず require 'set' と書く必要があります。

Setは「重複を許さない」というルールがあるため、間違えて同じ番号を二回登録してしまうミスを防げます。また、特定の番号がリストに入っているかどうかを調べるスピードが、配列(Array)に比べて圧倒的に速いという特徴があります。これが、大量のデータを扱う現場でSetが選ばれる理由です。これを「ブラックリスト」として活用してみましょう。


require 'set'

# 不良品や予約済みで販売できないIDをブラックリストに入れる
blacklist = Set.new([1005, 1010, 1025, 1050])

# 番号を追加してみる
blacklist.add(1080)

puts "現在のブラックリスト件数: #{blacklist.size}件"

実行結果は以下の通りです。


現在のブラックリスト件数: 5件

4. 実践!範囲からブラックリストを照合して弾く

4. 実践!範囲からブラックリストを照合して弾く
4. 実践!範囲からブラックリストを照合して弾く

それでは、用意した「在庫の範囲(Range)」から「ブラックリスト(Set)」に含まれる番号を除外して、実際に出荷できる番号だけを表示する仕組みを作ります。ここで reject(リジェクト)というメソッドを使います。これは「条件に当てはまるものを拒否する」という意味です。

パソコンの中では、1001番から順番に「この番号はブラックリストに入っているかな?」と一瞬で確認作業が行われます。Setを使っているおかげで、この照合作業は一瞬で終わります。初心者の方でも、この「全体から不要なものを引く」という考え方は非常に役立ちます。


require 'set'

# 在庫範囲とブラックリストの準備
id_range = (1001..1010)
bad_ids = Set.new([1003, 1007, 1008])

# 有効なIDだけを抽出する(ブラックリストに含まれるものは除く)
available_ids = id_range.reject { |id| bad_ids.include?(id) }

puts "出荷可能なIDリスト: #{available_ids.inspect}"

実行結果は以下の通りです。


出荷可能なIDリスト: [1001, 1002, 1004, 1005, 1006, 1009, 1010]

5. 性能の違いを理解する:なぜ配列ではなくSetなのか

5. 性能の違いを理解する:なぜ配列ではなくSetなのか
5. 性能の違いを理解する:なぜ配列ではなくSetなのか

プログラミングを学んでいると、「配列(Array)でも同じことができるのでは?」と思うかもしれません。確かに blacklist = [1003, 1007, 1008] と書いても動きます。しかし、データの数が数万件になったときに、その差がはっきりと出ます。

配列は「最初から順番に探す」ため、データが多いとパソコンが疲れてしまいます。一方、Setは「ハッシュテーブル」という技術を使い、番号を見た瞬間に「ある・ない」を判断できます。これを専門用語で O(1)(オー・ワン) の探索速度と呼びます。在庫管理システムがサクサク動くかどうかは、この道具選びにかかっているのです。

6. 応用テクニック:特定の帯域だけを許可する

6. 応用テクニック:特定の帯域だけを許可する
6. 応用テクニック:特定の帯域だけを許可する

ブラックリスト(除外)とは逆に、「特定の範囲に入っているものだけを許可する(ホワイトリスト)」という使い方もできます。例えば、「1000番から2000番までの正規ルートの製品だけを受け入れる」といった照合です。これには subset? というメソッドが使えます。

「この番号の集まりは、許可された範囲の中にすっぽり収まっているかな?」というチェックをします。不審な番号が混ざっていないか、データの整合性を守るための大切なテクニックです。Rubyなら、この複雑なチェックも直感的な英単語のような命令で実行できます。

7. 実際のシステムでの使われ方:セキュリティと効率

7. 実際のシステムでの使われ方:セキュリティと効率
7. 実際のシステムでの使われ方:セキュリティと効率

今回学んだ「範囲×Set」のテクニックは、在庫管理以外にも多くの場所で使われています。例えば、Webサイトへのアクセス制限です。特定の国や地域からのIPアドレス(ネット上の住所のような番号)の範囲をRangeで持ち、攻撃をしてくる危険なアドレスをSetでブラックリスト化して、それらを照合してブロックします。

また、スマートフォンのアプリで「特定のID帯のユーザーだけに新機能を公開する」といった時にも使われます。プログラミングの基礎を知ることは、私たちが普段使っている便利なサービスの裏側を知ることにも繋がります。一つ一つの命令はシンプルですが、組み合わせ次第で世界を支えるシステムに変わるのです。

8. 初心者が注意すべき「型変換」のポイント

8. 初心者が注意すべき「型変換」のポイント
8. 初心者が注意すべき「型変換」のポイント

最後に、よくある間違いについて触れておきます。Range(範囲)はそのままでは「リスト」ではなく「始まりと終わり」の情報しか持っていません。そのため、集合演算(引き算など)を直接行いたい場合は、一度 to_a(配列へ)や to_set(セットへ)という命令を使って、中身を具現化させる必要があります。

「型変換」という言葉は難しく聞こえますが、「折りたたまれた地図(Range)を広げて、一軒一軒の家(データ)が見える状態にする」ことだと思ってください。この変換を意識することで、Rubyのパワーを100%引き出せるようになります。焦らず、一つずつコードを書いて実行結果を見ることで、パソコンとの対話を楽しんでいきましょう!


require 'set'

# 範囲をそのままSetに変換して計算する例
all_range_set = (1..5).to_set
exclusion_set = Set.new([2, 4])

# 集合の引き算(差集合)で一気に除外!
result_set = all_range_set - exclusion_set

puts "最終的な集合: #{result_set.to_a}"

実行結果は以下の通りです。


最終的な集合: [1, 3, 5]
関連記事:
カテゴリの一覧へ
新着記事
New1
Ruby
“すべてはオブジェクト”を体感!初心者向けRubyのオブジェクト指向入門【irbで学ぶ】
New2
Ruby
Rubyの標準入出力を完全ガイド!puts・print・pの違いとデバッグ活用法
New3
Ruby
Gemとは?RubyGemsとBundlerを初心者向けに完全解説!依存関係管理も図解でわかりやすく理解
New4
Ruby
Rubyの文字エンコーディング入門!UTF-8・マジックコメント・外部/内部エンコーディングを完全解説
人気記事
No.1
Java&Spring記事人気No1
Ruby
Rubyのreduceとinject入門!合計計算や集計を初心者向けに分かりやすく解説
No.2
Java&Spring記事人気No2
Ruby
Rubyの文字列エンコーディング完全ガイド!Encoding・force_encoding・encodeを初心者向け解説
No.3
Java&Spring記事人気No3
Ruby
Rubyの始め方ガイド:インストールから最初のHello Worldまで(Windows/Mac/Linux)
No.4
Java&Spring記事人気No4
データベース
PostgreSQLのWHERE句を徹底解説!初心者でもわかるSQLデータ抽出の基本
No.5
Java&Spring記事人気No5
Ruby
Rubyのfind/detect/find_indexを徹底解説!目的のデータを素早く探す方法
No.6
Java&Spring記事人気No6
Ruby
Rubyで比較演算子を完全解説!==・===・<=>・eql? の使い分け
No.7
Java&Spring記事人気No7
Ruby
Rubyのselect/reject/filterの使い方を完全解説!初心者向けの条件抽出レシピ
No.8
Java&Spring記事人気No8
データベース
PostgreSQLで順位付け!ROW_NUMBER関数の使い方を初心者向けに徹底解説