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
十二、总结 #
本章我们学习了:
- 创建集合:Set.new、to_set、Set[]
- 基本操作:add、delete、include?
- 集合运算:并集、交集、差集、对称差
- 子集检查:subset?、superset?
- 集合遍历:each、map、select
- SortedSet:有序集合
- 实用场景:去重、标签系统、权限系统
接下来让我们学习Ruby的运算符!
最后更新:2026-03-27