集合、包和混合

简而言之,这些类通常包含无序的对象集合。Set 仅考虑这些对象是否存在,bags 可以容纳多个相同类型的对象,mixes 也允许分数(和负)权重。常规版本是不可变的,Hash 版本是可变的。

让我们详细说明一下。如果要收集容器中的对象但不关心这些对象的顺序,Raku 提供无序集合类型 Set, SetHash, Bag, BagHash, Mix, 和 MixHash. 由于无序,这些容器可以比 Lists 更有效地查找元素或处理重复的项目。

另一方面,如果你想获得包含的对象(元素)而没有重复并且你只关心元素是否在集合中,你可以使用 SetSetHash。如果你想消除重复但仍保留顺序,请查看 Listunique 例程。

如果你想跟踪每个对象出现的次数,你可以使用 BagBagHash。在这些Baggy 容器中,每个元素都有一个权重(无符号整数),表示同一个对象已包含在集合中的次数。

类型 MixMixHash 类似于 BagBagHash,但它们也允许分数和负权重

SetBagMiximmutable 类型。如果要在构造容器后添加或删除元素,请使用可变变体 SetHash, BagHash, 和 MixHash

六个集合类 SetSetHashBagBagHashMixMixHash,都有相似的语义。

首先,就它们而言,相同的对象引用相同的元素 - 其中使用 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),ArrayMix 等)并强制他们到在需要的地方设置。

在某些情况下,如果参数的类型是 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).