简而言之,这些类通常包含无序的对象集合。Set 仅考虑这些对象是否存在,bags 可以容纳多个相同类型的对象,mixes 也允许分数(和负)权重。常规版本是不可变的,Hash 版本是可变的。
让我们详细说明一下。如果要收集容器中的对象但不关心这些对象的顺序,Raku 提供*无序*集合类型 Set, SetHash, Bag, BagHash, Mix, 和 MixHash. 由于无序,这些容器可以比 Lists 更有效地查找元素或处理重复的项目。
六个集合类 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 上执行常见操作,例如并集和差集。其他操作包括布尔检查,例如对象是否是 Set
中的元素,或者一个 Set
是否是另一个 Set
的子集。
在某些情况下,如果参数的类型是 Bag,则中缀运算符将以与其行为方式不同但类似的方式运行 Set
参数。
下面的运算符都是 “Chaining infix” 的优先级。
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»
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»
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»
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»
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»
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»
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»
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»
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»
only sub infix:<⊇>($a, $b --> Bool)
另一个超集或集合相等运算符。
等价于 (>=)), 在代码点 U+2287 (SUPERSET OF OR EQUAL TO).
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»
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»
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>)
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>)
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>)
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)
。
only sub infix:<⊖>($a, $b --> Setty)
另一个对称差集运算符。它的优先级是 "Junctive or".
等价于 (^)), 在代码点 U+2296 (CIRCLED MINUS).
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
only sub infix:<⊍>(|p)
另一个 baggy 乘法运算符。 它的优先级是 "Junctive and".
等价于infix (.)), 在代码点 U+228D (MULTISET MULTIPLICATION).
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
only sub infix:<⊎>(|p)
另一个 baggy 加法 operator。 它的优先级是 "Junctive or".
等价于 link:https://docs.raku.org/routine/([()]), 在代码点 U+228E (MULTISET UNION).