集合、包和混合
简而言之,这些类通常包含无序的对象集合。Set 仅考虑这些对象是否存在,bags 可以容纳多个相同类型的对象,mixes 也允许分数(和负)权重。常规版本是不可变的,Hash 版本是可变的。
让我们详细说明一下。如果要收集容器中的对象但不关心这些对象的顺序,Raku 提供无序集合类型 Set, SetHash, Bag, BagHash, Mix, 和 MixHash. 由于无序,这些容器可以比 Lists 更有效地查找元素或处理重复的项目。
另一方面,如果你想获得包含的对象(元素)而没有重复并且你只关心元素是否在集合中,你可以使用 Set 或 SetHash。如果你想消除重复但仍保留顺序,请查看 List 的 unique 例程。
如果你想跟踪每个对象出现的次数,你可以使用 Bag 或 BagHash。在这些Baggy 容器中,每个元素都有一个权重(无符号整数),表示同一个对象已包含在集合中的次数。
类型 Mix 和 MixHash 类似于 Bag 和 BagHash,但它们也允许分数和负权重。
Set,Bag 和 Mix 是 immutable 类型。如果要在构造容器后添加或删除元素,请使用可变变体 SetHash, BagHash, 和 MixHash 。
六个集合类 Set
,SetHash
,Bag
,BagHash
,Mix
,MixHash
,都有相似的语义。
首先,就它们而言,相同的对象引用相同的元素 - 其中使用 WHICH 方法确定身份(即以相同的方式=== 运算符检查身份)。对于像 Str
这样的值类型,这意味着具有相同的值; 对于像“Array”这样的引用类型,它意味着引用相同的对象实例。
其次,它们提供了类似 Hash 的接口,其中集合的实际元素(可以是任何类型的对象)是“键”,关联的权重是“值”:
type of $a | value of $a{$b} if $b is an element | value of $a{$b} if $b is not an element |
---|---|---|
Set / SetHash | True | False |
Bag / BagHash | a positive integer | 0 |
Mix / MixHash | a non-zero real number | 0 |
Set/Bag operators
有几个中缀运算符致力于在 Set 上执行常见操作,例如并集和差集。其他操作包括布尔检查,例如对象是否是 Set
中的元素,或者一个 Set
是否是另一个 Set
的子集。
这些中缀可以使用代表函数的 UTF-8 字符编写(如 ∈ 或 ∪),或与 (elem) 或 (^)。
大多数情况下,显式地使用带有这些中缀的 Set
对象是不必要的。所有中缀运算符都将处理 Any 类型的任何对象的参数(例如, List),Array,Mix 等)并强制他们到在需要的地方设置。
在某些情况下,如果参数的类型是 Bag,则中缀运算符将以与其行为方式不同但类似的方式运行 Set
参数。
Operators that return Bool
下面的运算符都是 “Chaining infix” 的优先级。
infix (elem)
multi sub infix:<(elem)>($a, Any $b --> Bool)
multi sub infix:<(elem)>($a, Set $b --> Bool)
成员运算符。
返回i True
如果 $a
是 $b
中的一个元素。
say 2 (elem) (1, 2, 3).Set; # OUTPUT: «True»
say 4 (elem) (1, 2, 3).Set; # OUTPUT: «False»
infix ∈
only sub infix:<∈>($a, $b --> Bool)
另一个成员运算符。
等价于 (elem), 在代码点 U+2208 (ELEMENT OF).
infix ∉
only sub infix:<∉>($a, $b --> Bool)
非成员运算符。
等价于 !(elem)
, 例如, 返回 True
如果 $a
不是 $b
中的元素, 在代码点 U+2209 (NOT AN ELEMENT OF).
say 2 !(elem) (1, 2, 3).Set; # OUTPUT: «False»
say 4 !(elem) (1, 2, 3).Set; # OUTPUT: «True»
infix (cont)
multi sub infix:<(cont)>(Any $a, $b --> Bool)
multi sub infix:<(cont)>(Set $a, $b --> Bool)
包含运算符。
返回 True
如果 $a
contains $b
作为一个元素。
say (1, 2, 3).Set (cont) 2; # OUTPUT: «True»
say (1, 2, 3).Set (cont) 4; # OUTPUT: «False»
infix ∋
only sub infix:<∋>($a, $b --> Bool)
另一个包含运算符。
等价于 (cont), 在代码点 U+220B (CONTAINS AS MEMBER).
infix ∌
only sub infix:<∌>($a, $b --> Bool)
不包含运算符。
等价于 !(cont)
, 例如, 返回 True
如果 $a
不包含 $b
, 在代码点 U+220C (DOES NOT CONTAIN AS MEMBER).
say (1, 2, 3).Set !(cont) 2; # OUTPUT: «False»
say (1, 2, 3).Set !(cont) 4; # OUTPUT: «True»
infix (<=)
multi sub infix:<<(<=)>>(Any $a, Any $b --> Bool)
multi sub infix:<<(<=)>>(Setty $a, Setty $b --> Bool)
子集或相等运算符。
返回 True
如果 $a
是 $b
的一个子集(subset) 或 $a
和 $b
相等, 例如, 如果 $a
中所有的元素都是 $b
中的元素, 且 $a
的大小小于或等于 $b
的大小。
say (1, 2, 3).Set (<=) (3, 2, 1).Set; # OUTPUT: «True»
say (1, 3).Set (<=) (2, 1).Set; # OUTPUT: «False»
say ∅ (<=) (3, 2, 1).Set; # OUTPUT: «True»
infix ⊆
only sub infix:<⊆>($a, $b --> Bool)
另一个子集或相等运算符。
等价于 (<=), 在代码点 U+2286 (SUBSET OF OR EQUAL TO).
infix ⊈
only sub infix:<⊈>($a, $b --> Bool)
既不是子集运算符也不是相等运算符。
等价于 !(<=)
, 在代码点 U+2288 (NEITHER A SUBSET OF NOR EQUAL TO).
say (1, 2, 3).Set !(<=) (3, 2, 1).Set; # OUTPUT: «False»
say (1, 3).Set ⊈ (2, 1).Set; # OUTPUT: «True»
infix (<)
multi sub infix:<<(<)>>(Any $a, Any $b --> Bool)
multi sub infix:<<(<)>>(Setty $a, Setty $b --> Bool)
子集运算符。
返回 True
如果 $a
是 $b
的一个真子集(strict subset), 例如, $a
中的所有元素都是 $b
中的元素, 但是 $a
的大小比 $b
的大小要小。
say (1, 2, 3).Set (<) (3, 2, 1).Set; # OUTPUT: «False»
say (1, 3).Set (<) (3, 2, 1).Set; # OUTPUT: «True»
say ∅ (<) (3, 2, 1).Set; # OUTPUT: «True»
infix ⊂
only sub infix:<⊂>($a, $b --> Bool)
另一个子集运算符。
等价于 (<), 在代码点 U+2282 (SUBSET OF).
infix ⊄
only sub infix:<⊄>($a, $b --> Bool)
非子集运算符。
等价于 !(<)
, 在代码点 U+2284 (NOT A SUBSET OF).
say (1, 2, 3).Set !(<) (3, 2, 1).Set; # OUTPUT: «True»
say (1, 3).Set ⊄ (3, 2, 1).Set; # OUTPUT: «False»
infix (>=)
multi sub infix:<<(>=)>>(Any $a, Any $b --> Bool)
multi sub infix:<<(>=)>>(Setty $a, Setty $b --> Bool)
超集或相等运算符。
像 (<=) 但是翻转参数。 返回 True
如果 $a
是 $b
的超集(superset) 或与 $b
相等。
say (1, 2, 3).Set (>=) (3, 2, 1).Set; # OUTPUT: «True»
say (1, 3).Set (>=) (3, 2, 1).Set; # OUTPUT: «False»
say ∅ (>=) (3, 2, 1).Set; # OUTPUT: «False»
infix ⊇
only sub infix:<⊇>($a, $b --> Bool)
另一个超集或集合相等运算符。
等价于 (>=), 在代码点 U+2287 (SUPERSET OF OR EQUAL TO).
infix ⊉
only sub infix:<⊉>($a, $b --> Bool)
既不是超集运算符, 也非集合相等运算符。
等价于 !(>=)
, 在代码点 U+2289 (NEITHER A SUPERSET OF NOR EQUAL TO).
say (1, 2, 3).Set !(>=) (3, 2, 1).Set; # OUTPUT: «False»
say (1, 3).Set ⊉ (3, 2, 1).Set; # OUTPUT: «True»
infix (>)
multi sub infix:<<(>)>>(Any $a, Any $b --> Bool)
multi sub infix:<<(>)>>(Setty $a, Setty $b --> Bool)
超集运算符。
像 (<) 但是反转参数。返回 True
如果 $a
是 $b
的一个严格超集(strict superset)。
say (1, 2, 3, 4).Set (>) (3, 2, 1).Set; # OUTPUT: «True»
say (1, 3).Set (>) (3, 2, 1).Set; # OUTPUT: «False»
say ∅ (>) (3, 2, 1).Set; # OUTPUT: «False»
infix ⊃
only sub infix:<⊃>($a, $b --> Bool)
另一个超集运算符。
等价于 (>), 在代码点 U+2283 (SUPERSET OF).
infix ⊅
only sub infix:<⊅>($a, $b --> Bool)
非超集运算符。
等价于!(>)
, 在代码点 U+2285 (NOT A SUPERSET OF).
say (1, 2, 3, 4).Set !(>) (3, 2, 1).Set; # OUTPUT: «False»
say (1, 3).Set ⊅ (3, 2, 1).Set; # OUTPUT: «True»
Operators that return Set
or Bag
infix (|)
only sub infix:<(|)>(**@p)
并集运算符。 它的优先级是 “Junctive Or”.
返回它所有参数的并集。通常, 这创建一个新的包含参数的所有元素的集合:
<a a b c d> (|) <h g f e d c> (|) <i j> === set <a b c d e f g h i j>
如果它的任何参数是 “Baggy”,它会创建一个新的 “Bag”,其中包含参数的所有元素,每个元素都按照该元素出现的最高权重进行加权。
bag(<a a b c a>) (|) bag(<a a b c c>) === bag(<a a a b c c>)
infix ∪
only sub infix:<∪>(|p)
另一个并集运算符。它的优先级是 “Junctive or”.
等价于 (|), 在代码点 U+222A (UNION).
infix (&)
only sub infix:<(&)>(**@p)
交集运算符。它的优先级是 “Junctive and”.
返回它所有参数的交集。通常, 这创建一个包含所有参数都共有的元素的新的集合。
<a b c> (&) <b c d> === set <b c>
<a b c d> (&) <b c d e> (&) <c d e f> === set <c d>
如果任何参数是 “Baggy”,则结果是一个包含公共元素的新 “Bag”,每个元素都由最大共同权重(这是所有参数中该元素的权重的最小值)加权。
bag(<a a b c a>) (&) bag(<a a b c c>) === bag(<a a b c>)
infix ∩
only sub infix:<∩>(|p)
另一个交集运算符。它的优先级是 “Junctive and”.
等价于 (&), 在代码点 U+2229 (INTERSECTION).
infix (-)
only sub infix:<(-)>(**@p)
差集运算符。它优先于“Junctive or”。
返回其所有参数的差集。通常,这将返回由第一个参数具有的所有元素组成的 “Set”,但不包括其余元素,即第一个参数的所有元素,减去其他参数中的元素。
如果第一个参数是 “Baggy”,则返回一个 “Bag”,其中包含第一个参数的每个元素,其权重减去每个其他参数中该元素的权重。
bag(<a a b c a d>) (-) bag(<a a b c c>) === bag(<a d>)
bag(<a a a a c d d d>) (-) bag(<a b d a>) (-) bag(<d c>) === bag(<a a d>)
infix ∖
only sub infix:<<"\x2216">>(|p)
另一个差集运算符. 它的优先级是 “Junctive or”.
等价于 (-).
infix (^)
multi sub infix:<(^)>(Any $a, Any $b --> Setty)
multi sub infix:<(^)>(Set $a, Set $b --> Setty)
对称差集运算符。 它的优先级是 “Junctive or“。
返回所有参数的对称差集,即 Set
由 $a
所有的元素组成,但 $b
没有,所有元素 $b
都有但是 $a
没有。 相当于 ($a ∖ $b) ∪ ($b ∖ $a)
。
infix ⊖
only sub infix:<⊖>($a, $b --> Setty)
另一个对称差集运算符。它的优先级是 “Junctive or”.
等价于 (^), 在代码点 U+2296 (CIRCLED MINUS).
infix (.)
only sub infix:<(.)>(**@p)
Baggy 乘法运算符。它的优先级是 “Junctive and”。
返回其参数的 Baggy 倍数,即 Bag
包含参数的每个元素,其中参数的元素权重相乘以获得新的权重。
<a b c> (.) <a b c d> === bag <a b c> # Since 1 * 0 == 0, in the case of 'd'
bag(<a a b c a d>) (.) bag(<a a b c c>) === ("a"=>6,"c"=>2,"b"=>1).Bag
infix ⊍
only sub infix:<⊍>(|p)
另一个 baggy 乘法运算符。 它的优先级是 “Junctive and”.
等价于infix (.), 在代码点 U+228D (MULTISET MULTIPLICATION).
infix (+)
only sub infix:<(+)>(**@p)
Baggy 加法运算符。它的优先级是 “Junctive or”。
返回其参数的 Baggy 加法,即包含参数的每个元素,其中参数的权重加在一起以获得新的权重。
bag(<a a b c a d>) (+) bag(<a a b c c>) === ("a"=>5,"c"=>3,"b"=>2,"d"=>1).Bag
infix ⊎
only sub infix:<⊎>(|p)
另一个 baggy 加法 operator。 它的优先级是 “Junctive or”.
等价于 (+), 在代码点 U+228E (MULTISET UNION).
term ∅
等价于 set(), 即空集, 在代码点 U+2205 (EMPTY SET).