class Bag does Baggy { }

Bag 是一个不可变的袋/多重集,实现 Associative,这意味着一个特定顺序中没有不同元素的集合,每个元素都有一个分配给它们的整数权重,表示该元素的多少副本被认为“在袋中”。(对于可变袋,请改用 BagHash。)

Bag 通常用于执行加权随机选择 - 请参阅 .pick.roll

允许任何类型的对象/值作为袋元素。在 Bag 中,使用 === 运算符比较为正数的项目被认为是相同的元素,其数量作为其权重。但您也可以轻松地获取展开的项目列表(不带顺序)

my $breakfast = bag <spam eggs spam spam bacon spam>;
 
say $breakfast.elems;      # OUTPUT: «3␤» 
say $breakfast.keys.sort;  # OUTPUT: «bacon eggs spam␤» 
 
say $breakfast.total;      # OUTPUT: «6␤» 
say $breakfast.kxxv.sort;  # OUTPUT: «bacon eggs spam spam spam spam␤» 

可以使用 { } 后缀运算符< > 后缀运算符Bag 视为对象哈希,对于文字字符串键,返回相应的整数权重,对于是袋元素的键,返回 0

my $breakfast = bag <spam eggs spam spam bacon spam>;
say $breakfast<bacon>;    # OUTPUT: «1␤» 
say $breakfast<spam>;     # OUTPUT: «4␤» 
say $breakfast<sausage>;  # OUTPUT: «0␤»

创建 Bag 对象§

可以使用 bag 子例程(或 Bag.new,它是其简写)来组合 Bag。任何位置参数,无论其类型如何,都成为袋的元素

my $n = bag "a" => 0"b" => 1"c" => 2"c" => 2;
say $n.keys.raku;        # OUTPUT: «(:c(2), :b(1), :a(0)).Seq␤» 
say $n.keys.map(&WHAT);  # OUTPUT: «((Pair) (Pair) (Pair))␤» 
say $n.values.raku;      # OUTPUT: «(2, 1, 1).Seq␤»

或者,可以在现有对象上调用 .Bag 转换器(或其函数形式 Bag())以将其转换为 Bag。它的语义取决于对象的类型和内容。通常,它在列表上下文中计算对象,并创建一个以结果项目作为元素的袋,尽管对于类似哈希的对象或 Pair 项目,只有键成为袋的元素,而(累积)值成为关联的整数权重

my $n = ("a" => 0"b" => 1"c" => 2"c" => 2).Bag;
say $n.keys.raku;        # OUTPUT: «("b", "c").Seq␤» 
say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤» 
say $n.values.raku;      # OUTPUT: «(1, 4).Seq␤»

此外,您可以通过对 List 等其他类型的对象使用袋运算符(请参见下一节)来获取 Bag,这些运算符的行为就像在执行操作之前在内部调用 .Bag。但请注意这些运算符的紧密优先级,这可能需要您在参数周围使用括号

say (1..5(+) 4;  # OUTPUT: «Bag(1 2 3 4(2) 5)␤»

您还可以使用 .new 方法创建 Bag

my $breakfast = Bag.new( <spam eggs spam spam bacon spam> );

从 6.d(2019.03 及更高版本)开始,您还可以将此语法用于 Bag 的参数化,以指定可接受的值类型

# only allow strings (Str) in the Bag 
my $breakfast = Bag[Str].new( <spam eggs spam spam bacon spam> );
 
# only allow whole numbers (Int) in the Bag 
my $breakfast = Bag[Int].new( <spam eggs spam spam bacon spam> );
# Type check failed in binding; expected Int but got Str ("spam")

最后,您可以通过使用 is 特性来创建伪装成哈希的 Bag

my %b is Bag = <a b c>;
say %b<a>;  # OUTPUT: «True␤» 
say %b<d>;  # OUTPUT: «False␤»

从 6.d(2019.03 及更高版本)开始,此语法还允许您指定您希望允许的值类型

# limit to strings 
my %b is Bag[Str= <a b c>;
say %b<a>;  # OUTPUT: «True␤» 
say %b<d>;  # OUTPUT: «False␤» 
 
# limit to whole numbers 
my %b is Bag[Int= <a b c>;
# Type check failed in binding; expected Int but got Str ("a")

运算符§

有关适用于 Bag 等类型的“集合运算符”的完整列表,请参阅 具有集合语义的运算符

示例

my ($a$b= bag(224), bag(2334);
 
say $a (<) $b;   # OUTPUT: «False␤» 
say $a (<=) $b;  # OUTPUT: «False␤» 
say $a (^) $b;   # OUTPUT: «Bag(3(2) 2)␤» 
say $a (+) $b;   # OUTPUT: «Bag(2(3) 4(2) 3(2))␤» 
 
# Unicode versions: 
say $a  $b;  # OUTPUT: «False␤» 
say $a  $b;  # OUTPUT: «False␤» 
say $a  $b;  # OUTPUT: «Bag(3(2) 2)␤» 
say $a  $b;  # OUTPUT: «Bag(2(3) 4(2) 3(2))␤» 

子例程§

sub bag§

sub bag(*@args --> Bag)

@args 创建一个新的 Bag

有关 reverse 和排序的说明§

此方法继承自 Any,但是,Mixes 没有固有顺序,你不应该相信它会返回一致的输出。

另请参见§

集合、包和混合

类型图§

Bag 的类型关系
raku-type-graph Bag Bag Any Any Bag->Any Baggy Baggy Bag->Baggy Mu Mu Any->Mu Associative Associative QuantHash QuantHash QuantHash->Associative Baggy->QuantHash

展开上面的图表