Ruby集合 #

一、集合概述 #

集合(Set)是Ruby标准库中的数据结构,表示不重复元素的集合。集合中的元素唯一,且没有顺序。

ruby
require 'set'

set = Set.new([1, 2, 3, 2, 1])
set.class
set.to_a

二、创建集合 #

2.1 Set.new #

ruby
require 'set'

Set.new
Set.new([1, 2, 3])
Set.new(1..5)
Set.new([1, 2, 3]) { |x| x * 2 }
Set.new(["a", "b", "c"])

2.2 数组转集合 #

ruby
require 'set'

[1, 2, 3, 2, 1].to_set
%w[apple banana cherry].to_set
(1..5).to_set

2.3 字面量语法(需要扩展) #

ruby
require 'set'

Set[1, 2, 3]
Set["a", "b", "c"]
Set[]

三、集合基本操作 #

3.1 添加元素 #

ruby
require 'set'

set = Set.new

set.add(1)
set << 2
set.add?(3)
set.add?(1)
set.merge([4, 5, 6])

3.2 删除元素 #

ruby
require 'set'

set = Set[1, 2, 3, 4, 5]

set.delete(3)
set.delete?(10)
set.subtract([1, 2])
set.clear

3.3 包含检查 #

ruby
require 'set'

set = Set[1, 2, 3]

set.include?(2)
set.member?(2)
set === 2
set.include?(10)

3.4 大小与空检查 #

ruby
require 'set'

set = Set[1, 2, 3]

set.size
set.length
set.empty?
set.clear
set.empty?

四、集合运算 #

4.1 并集 #

ruby
require 'set'

a = Set[1, 2, 3]
b = Set[3, 4, 5]

a | b
a.union(b)
a + b
a.merge(b)

4.2 交集 #

ruby
require 'set'

a = Set[1, 2, 3, 4]
b = Set[3, 4, 5, 6]

a & b
a.intersection(b)

4.3 差集 #

ruby
require 'set'

a = Set[1, 2, 3, 4]
b = Set[3, 4, 5, 6]

a - b
a.difference(b)
b - a

4.4 对称差 #

ruby
require 'set'

a = Set[1, 2, 3, 4]
b = Set[3, 4, 5, 6]

(a | b) - (a & b)
a ^ b

4.5 子集与超集 #

ruby
require 'set'

a = Set[1, 2]
b = Set[1, 2, 3, 4]

a.subset?(b)
a.proper_subset?(b)
b.superset?(a)
b.proper_superset?(a)

Set[1, 2].subset?(Set[1, 2])
Set[1, 2].proper_subset?(Set[1, 2])

4.6 相交检查 #

ruby
require 'set'

a = Set[1, 2, 3]
b = Set[3, 4, 5]
c = Set[6, 7, 8]

a.intersect?(b)
a.intersect?(c)
a.disjoint?(b)
a.disjoint?(c)

五、集合遍历 #

5.1 each遍历 #

ruby
require 'set'

set = Set[1, 2, 3, 4, 5]

set.each { |n| puts n }
set.each_with_index { |n, i| puts "#{i}: #{n}" }

5.2 map转换 #

ruby
require 'set'

set = Set[1, 2, 3, 4, 5]

set.map { |n| n * 2 }
set.map { |n| n * 2 }.to_set
set.collect { |n| n ** 2 }

5.3 select过滤 #

ruby
require 'set'

set = Set[1, 2, 3, 4, 5]

set.select { |n| n.even? }
set.reject { |n| n.even? }
set.filter { |n| n > 2 }

5.4 reduce聚合 #

ruby
require 'set'

set = Set[1, 2, 3, 4, 5]

set.reduce(:+)
set.reduce(0) { |sum, n| sum + n }
set.sum

六、集合比较 #

6.1 相等比较 #

ruby
require 'set'

a = Set[1, 2, 3]
b = Set[3, 2, 1]
c = Set[1, 2, 3, 4]

a == b
a == c
a.eql?(b)

6.2 太空船运算符 #

ruby
require 'set'

a = Set[1, 2]
b = Set[1, 2, 3]

a <=> b
b <=> a
a <=> a

七、集合分类 #

7.1 分类 #

ruby
require 'set'

set = Set[1, 2, 3, 4, 5, 6]

set.classify { |n| n.even? }
set.classify { |n| n % 3 }
set.group_by { |n| n.even? }

7.2 分割 #

ruby
require 'set'

set = Set[1, 2, 3, 4, 5, 6]

set.divide { |a, b| (a - b).abs == 1 }
set.divide { |a, b| a.even? == b.even? }

八、集合转换 #

8.1 转数组 #

ruby
require 'set'

set = Set[1, 2, 3]

set.to_a
set.to_a.sort
set.entries

8.2 转字符串 #

ruby
require 'set'

set = Set[1, 2, 3]

set.to_s
set.inspect
set.to_a.join(", ")

8.3 冻结 #

ruby
require 'set'

set = Set[1, 2, 3]
set.freeze

set.add(4)

九、SortedSet #

9.1 创建有序集合 #

ruby
require 'set'

sorted = SortedSet.new([3, 1, 4, 1, 5, 9, 2, 6])
sorted.to_a

SortedSet["c", "a", "b"].to_a

9.2 有序集合操作 #

ruby
require 'set'

sorted = SortedSet[3, 1, 4, 1, 5]

sorted.first
sorted.last
sorted.min
sorted.max
sorted.to_a

十、实用示例 #

10.1 数组去重 #

ruby
require 'set'

def unique_elements(arr)
  arr.to_set.to_a
end

unique_elements([1, 2, 2, 3, 3, 3])

10.2 查找共同元素 #

ruby
require 'set'

def common_elements(*arrays)
  arrays.map(&:to_set).reduce(:&).to_a
end

common_elements([1, 2, 3], [2, 3, 4], [3, 4, 5])

10.3 查找唯一元素 #

ruby
require 'set'

def unique_to_first(arr1, arr2)
  (arr1.to_set - arr2.to_set).to_a
end

unique_to_first([1, 2, 3, 4], [3, 4, 5, 6])

10.4 标签系统 #

ruby
require 'set'

class Taggable
  attr_reader :tags

  def initialize
    @tags = Set.new
  end

  def add_tag(tag)
    @tags << tag
  end

  def remove_tag(tag)
    @tags.delete(tag)
  end

  def tagged_with?(*tags)
    tags.to_set.subset?(@tags)
  end

  def has_any_tag?(*tags)
    @tags.intersect?(tags.to_set)
  end
end

item = Taggable.new
item.add_tag(:ruby)
item.add_tag(:rails)
item.add_tag(:web)

item.tagged_with?(:ruby, :rails)
item.tagged_with?(:ruby, :python)
item.has_any_tag?(:python, :java)

10.5 权限系统 #

ruby
require 'set'

class Permission
  ADMIN = Set[:read, :write, :delete, :manage_users]
  EDITOR = Set[:read, :write, :delete]
  VIEWER = Set[:read]

  def self.check(user_permissions, required)
    required.to_set.subset?(user_permissions.to_set)
  end
end

Permission.check(Permission::ADMIN, [:read, :write])
Permission.check(Permission::VIEWER, [:read, :write])

10.6 集合运算工具 #

ruby
require 'set'

class SetOperations
  def self.union(*arrays)
    arrays.map(&:to_set).reduce(:|).to_a
  end

  def self.intersection(*arrays)
    arrays.map(&:to_set).reduce(:&).to_a
  end

  def self.difference(arr1, arr2)
    (arr1.to_set - arr2.to_set).to_a
  end

  def self.symmetric_difference(arr1, arr2)
    ((arr1.to_set | arr2.to_set) - (arr1.to_set & arr2.to_set)).to_a
  end
end

SetOperations.union([1, 2], [2, 3], [3, 4])
SetOperations.intersection([1, 2, 3], [2, 3, 4], [3, 4, 5])
SetOperations.difference([1, 2, 3, 4], [3, 4, 5, 6])
SetOperations.symmetric_difference([1, 2, 3], [3, 4, 5])

十一、集合与数组的选择 #

11.1 使用集合的场景 #

  • 需要唯一元素
  • 频繁的成员检查
  • 集合运算(并集、交集、差集)
  • 不关心顺序

11.2 使用数组的场景 #

  • 需要保持顺序
  • 需要索引访问
  • 允许重复元素
  • 需要排序

11.3 性能对比 #

ruby
require 'set'
require 'benchmark'

arr = (1..10000).to_a
set = arr.to_set

Benchmark.bm do |x|
  x.report("Array#include?: ") do
    1000.times { arr.include?(5000) }
  end

  x.report("Set#include?: ") do
    1000.times { set.include?(5000) }
  end
end

十二、总结 #

本章我们学习了:

  1. 创建集合:Set.new、to_set、Set[]
  2. 基本操作:add、delete、include?
  3. 集合运算:并集、交集、差集、对称差
  4. 子集检查:subset?、superset?
  5. 集合遍历:each、map、select
  6. SortedSet:有序集合
  7. 实用场景:去重、标签系统、权限系统

接下来让我们学习Ruby的运算符!

最后更新:2026-03-27