2026a

# 集合和数据结构


# 迭代

序列迭代由 iterate 实现。 广义的 for 循环

for i in iter   # or  "for i = iter"
    # body
end

被转换成

next = iterate(iter)
while next !== nothing
    (i, state) = next
    # body
    next = iterate(iter, state)
end

state 对象可以是任何对象,并且对于每个可迭代类型应该选择合适的 state 对象。 有关定义自定义可迭代类型的更多详情,请参阅手册中有关迭代接口的部分。

函数名 简介
iterate 将迭代器推进到下一个元素
Base.IteratorSize 用于判断迭代器的长度属性,帮助选择合适的空间分配策略
Base.IteratorEltype 用于判断迭代器的元素类型是否已知,辅助选择预分配具体类型结果还是动态确定结果类型的算法

以下类型均完全实现了上述函数:

  • AbstractRange
  • UnitRange
  • Tuple
  • Number
  • AbstractArray
  • BitSet
  • IdDict
  • Dict
  • WeakKeyDict
  • EachLine
  • AbstractString
  • Set
  • Pair
  • NamedTuple

# 构造函数和类型

函数名 简介
AbstractRange 表示具有元素类型 T 的范围的超类型
OrdinalRange 表示具有固定步长且元素类型为离散类型的序数区间
AbstractUnitRange 表示步长为单位步长的区间类型
StepRange 表示步长固定且元素间隔均匀的区间类型
UnitRange 表示一个以起点和终点为界、元素间隔为 1 的区间类型
LinRange 表示一个在起点和终点之间均匀分布指定数量元素的区间类型

# 通用集合

函数名 简介
isempty 判断一个集合是否为空
Base.isdone 用于快速判断迭代器是否已经完成
empty! 清空集合中的所有元素
length 返回集合中元素的数量
Base.checked_length 计算集合的长度,同时在结果可能溢出时进行检查

以下类型均完全实现了上述函数:

  • AbstractRange
  • UnitRange
  • Tuple
  • Number
  • AbstractArray
  • BitSet
  • IdDict
  • Dict
  • WeakKeyDict
  • AbstractString
  • Set
  • NamedTuple

# 可迭代集合

函数名 简介
in 判断指定元素是否存在于集合中,返回布尔值
判断指定元素是否不在集合中
eltype 确定遍历指定类型集合时生成的元素类型
indexin 返回一个数组,记录每个在集合 a 中且属于集合 b 的元素在 b 中的第一个索引位置, a 中不属于 b 的元素对应位置为空
unique 返回一个数组,包含集合中按首次出现顺序排列的唯一元素,保持输入元素类型不变
unique! 对于集合中通过函数映射得到的每个唯一值,选择一个对应元素,并返回经过筛选后的集合
allunique 如果集合中的所有元素两两不相等,则返回真
allequal 如果集合中的所有元素相等,则返回真
reduce 使用指定的二元操作符对集合中的元素进行归约运算
foldl 与归约操作类似,但保证从左到右的结合顺序
foldr 与归约操作类似,但保证从右到左的结合顺序
maximum 返回对集合中每个元素应用函数后得到的最大结果
maximum! 计算集合中单例维度上的最大值,并将结果写回该集合
minimum 返回对集合中每个元素应用函数后得到的最小结果
minimum! 计算集合中单例维度上的最小值,并将结果写回该集合
extrema 一次遍历同时计算集合中的最小值和最大值,并以二元组形式返回
extrema! 计算集合中单例维度上的最小值和最大值,并将结果写回该集合
argmax 区间可能包含多个最大值,argmax 返回其中一个最大值的索引,但不一定是第一个出现的位置
argmin 区间可能包含多个最小值,argmin 返回其中一个最小值的索引,但不一定是第一个出现的位置
findmax 返回使函数值最大的输出及其对应输入的索引
findmin 返回使函数值最小的输出及其对应输入的索引
findmax! 计算集合在单例维度上的最大值及其对应的线性索引,并将结果存储回相应变量
findmin! 计算集合在单例维度上的最小值及其对应的线性索引,并将结果存储回相应变量
sum 对集合中每个元素应用函数后,将所有结果求和
sum! 计算集合在单例维度上的元素和,并将结果写回该集合
prod 返回对集合中每个元素应用函数后的乘积结果
prod! 计算集合在单例维度上的元素乘积,并将结果写回该集合
any 判断布尔集合中是否存在任意元素为真,一旦遇到第一个真值即返回真(短路求值)
any! 判断集合在单例维度上是否存在真值,并将结果写回该集合
all 判断布尔集合中是否所有元素均为真,一旦遇到第一个假值即返回假(短路求值)
all! 判断集合在单例维度上是否所有值均为真,并将结果写回该集合
count 统计集合中满足函数条件的元素个数
foreach 对可迭代集合中的每个元素调用函数
map 对集合中的每个元素应用函数进行转换
map! 与 map 类似,但将结果存储到指定的目标集合中,目标集合大小至少与最小输入集合相同
mapreduce 对集合中的每个元素应用函数,然后使用二元操作符对结果进行归约
mapfoldl 类似于 mapreduce,但保证从左到右的结合顺序
mapfoldr 类似于 mapreduce,但保证从右到左的结合顺序
first 获取可迭代集合的第一个元素,或前 n 个元素
last 获取有序集合的最后一个元素,或最后 n 个元素
Base.front 返回去掉最后一个元素后的元组
Base.tail 返回去掉第一个元素后的元组
step 获取一个 AbstractRange 对象的步长
collect 返回集合或迭代器中的所有元素组成的数组
filter 返回集合的副本,移除不满足条件的元素
filter! 更新集合,移除不满足条件的元素
replace 返回集合的副本,将指定元素替换为新的值,且可限制替换次数
replace! 将集合中的指定元素替换为新的值,且可限制替换次数
Base.rest 返回集合的尾部,从指定的迭代状态开始
Base.split_rest 返回集合尾部的拆分,起始于指定的迭代状态

# 可索引集合

函数名 简介
getindex 从集合中获取给定键或索引处存储的值
setindex! 将给定的值存储在集合中指定的键或索引位置
firstindex 返回集合的第一个索引
lastindex 返回集合的最后一个索引

以下类型均完全实现了上述函数:

  • Array
  • BitArray
  • AbstractArray
  • SubArray

以下类型仅实现了部分上述函数:

  • AbstractRange
  • UnitRange
  • Tuple
  • AbstractString
  • Dict
  • IdDict
  • WeakKeyDict
  • NamedTuple

# 字典

Dict 是一个标准字典。 其实现利用了 hash 作为键的哈希函数和 isequal 来决定是否相等。 对于自定义类型,可以定义这两个函数来重载它们在哈希表内的存储方式。

IdDict 是一种特殊的哈希表,在里面键始终是对象标识符。

WeakKeyDict 是一个哈希表的实现,里面键是对象的弱引用, 所以即使键在哈希表中被引用也有可能被垃圾回收。 它像 Dict 一样使用 hash 来做哈希和 isequal 来做相等判断, 但是它不会在插入时转换键,这点不像 Dict

将用 => 构造的成对对象传递给 Dict 构造函数,可以创建字典:Dict("A"=>1, "B"=>2)。 该调用将尝试从键和值推断出类型信息(例如,本示例创建了一个 Dict{String, Int64})。 要明确指定类型请使用语法 Dict{KeyType, ValueType}(...)。 例如,Dict{String, Int32}("A"=>1, "B"=>2)

字典也可以用生成器创建。 例如:Dict(i => f(i) for i = 1:10)

对于字典 D,若键 x 的值存在,则语法 D[x] 返回 x 的值;否则抛出一个错误。 D[x] = y 存储键值对 x => yD 中,会覆盖键 x 的已有的值。 多个参数传入D[...] 会被转化成元组; 例如:语法 D[x,y] 等于 D[(x,y)],也就是说,它指向键为元组 (x,y) 的值。

函数名 简介
AbstractDict 字典类类型的超类型
Dict 构造一个哈希表
IdDict 构造一个哈希表,使用 objectid 作为哈希函数,并使用 === 作为相等性比较
WeakKeyDict 构造一个哈希表,其中键是对对象的弱引用
Base.ImmutableDict 实现为不可变链表的字典
haskey 判断集合中是否存在给定键的映射关系
get 返回给定键对应的值,如果不存在则返回默认值
get! 返回给定键对应的值,如果该键没有映射,则存储默认值并返回这个默认值
getkey 返回集合中与给定键匹配的键,如果不存在则返回默认值
delete! 删除集合中给定键的映射,并返回该集合
keys 对于具有键和值的迭代器或集合,返回一个键的迭代器
values 对于具有键和值的迭代器或集合,返回一个值的迭代器
pairs 一个迭代器,访问数组中的每个元素
merge 从给定的集合构造一个合并后的集合,作为 mergewith 的别名仍然可用,以保持向后兼容性
mergewith 从给定的集合构造一个合并后的集合
merge! 使用其他集合中的键值对更新集合,作为 mergewith! 的别名仍然可用,以保持向后兼容性
mergewith! 使用其他集合中的键值对更新集合
sizehint! 建议集合 s 预留至少 n 个元素的容量
keytype 返回数组的键类型
valtype 返回数组的值类型

以下类型均完全实现了上述函数:

  • Dict
  • IdDict
  • WeakKeyDict

以下类型仅实现了部分上述函数:

  • Set
  • BitSet
  • IdSet
  • EnvDict
  • Array
  • BitArray
  • ImmutableDict
  • PersistentDict
  • Iterators.Pairs

# 类似 Set 的集合

函数名 简介
AbstractSet 集合类型的超类型
Set 可变容器,提供快速的成员测试
BitSet 构造一个由给定可迭代对象生成的排序整数集合,或者返回一个空集合
union 构造一个包含所有传入参数中所有不同元素的对象
union! 构造传入集合的并集,并用结果覆盖集合
intersect 构造一个集合,包含所有传入参数中都出现的元素(交集)
setdiff 构造一个集合,包含集合中的元素,但不包括任何在 itrs 中的可迭代对象中的元素
setdiff! 从集合中(原地)移除 itrs 中每个可迭代对象的元素
symdiff 构造传入集合的对称差集
symdiff! 构造传入集合的对称差集,并用结果覆盖集合
intersect! 求所有传入集合的交集,并用结果覆盖集合
issubset 判断集合 a 中的每个元素是否都在集合 b 中,使用 in 进行检查
⊈(a, b)判断 a 是否不是 b 的子集
⊊(a, b)判断 a 是否是 b 的子集,但不等于 b
issetequal 判断 a 和 b 是否具有相同的元素
isdisjoint 判断集合 a 和 b 是否不相交。等价于 isempty(a ∩ b),但在可能的情况下更加高效

以下类型均完全实现了上述函数:

  • Set
  • BitSet
  • IdSet

以下类型仅实现了部分上述函数:

  • Array

# 双端队列

函数名 简介
push! 向集合中插入一个或多个元素
pop! 从集合中移除一个元素并返回该元素
popat! 移除并返回集合中指定索引处的元素
pushfirst! 将一个或多个元素插入到集合的开头
popfirst! 从集合中移除第一个元素
insert! 在集合的指定索引位置插入一个元素
deleteat! 移除集合中指定索引处的元素,并返回修改后的集合
keepat! 移除集合中所有不在迭代器中指定的索引位置的元素,并返回修改后的集合
splice! 移除指定索引位置的元素,并返回被移除的元素
resize! 将集合 a 调整为包含 n 个元素
append! 对于有序容器集合,将每个集合的元素添加到集合的末尾
prepend! 将每个集合的元素插入到集合的开头

以下类型均完全实现了上述函数:

  • Vector
  • BitVector

# 集合相关的实用工具

函数名 简介
Pair 构造一个 Pair 对象,其类型为 Pair{typeof(x), typeof(y)}
Iterators.Pairs 将一个可索引容器转换为相同数据的字典视图