class Mix does Mixy { }

Mix 是一个不可变的集合,其中包含没有特定顺序的不同元素,每个元素都分配了一个实数权重。(对于可变 mix,请参阅 MixHash。)

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

任何类型的对象/值都可以作为 mix 元素。在 Mix 中,使用 === 运算符比较为正数的项目被视为相同的元素,具有组合权重。

my $recipe = (butter => 0.22sugar => 0.1,
              flour => 0.275sugar => 0.02).Mix;
 
say $recipe.elems;      # OUTPUT: «3␤» 
say $recipe.keys.sort;  # OUTPUT: «butter flour sugar␤» 
say $recipe.pairs.sort# OUTPUT: «"butter" => 0.22 "flour" => 0.275 "sugar" => 0.12␤» 
say $recipe.total;      # OUTPUT: «0.615␤» 

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

my $recipe = (butter => 0.22sugar => 0.1,
              flour => 0.275sugar => 0.02).Mix;
say $recipe<butter>;     # OUTPUT: «0.22␤» 
say $recipe<sugar>;      # OUTPUT: «0.12␤» 
say $recipe<chocolate>;  # OUTPUT: «0␤»

创建 Mix 对象§

可以使用 mix 子例程(或 Mix.new,它是其简写)来组合 Mix。任何位置参数(无论其类型如何)都成为 mix 的元素 - 对于每次出现参数,权重为 1

my $n = mix "a""a""b" => 03.14ππ# The Pair is a single element 
say $n.keys.map: *.^name# OUTPUT: «(Rat Pair Num Str)␤» 
say $n.pairs;
# OUTPUT: «(3.14 => 1 (b => 0) => 1 3.141592653589793 => 2 a => 2)␤»

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

my $n = ("a""a""b" => 0"c" => 3.14).Mix;
say $n.keys.map(&WHAT);  # OUTPUT: «((Str) (Str))␤» 
say $n.pairs;            # OUTPUT: «(a => 2 c => 3.14)␤»

如上文中的 b,值为 0 的元素将从 Mix 中消除。

或者,由于 MixAssociative,我们可以使用 % 符号来声明它们;在这种情况下,我们可以使用 is 来声明它们的类型

my %n is Mix = ("a""a""b" => 0"c" => 3.14);
say %n.^name# OUTPUT: «Mix␤» 
say %n;       # OUTPUT: «Mix(a(2) c(3.14))␤»

从 6.d(2019.03 及更高版本)开始,还可以指定希望在 Mix 中允许的值类型。这可以在调用 .new 时完成

# only allow strings 
my $n = Mix[Str].new: <a b b c c c>;

或使用伪装语法

# only allow strings 
my %m is Mix[Str= <a b b c c c>;
say %m<b>;  # OUTPUT: «2␤» 
say %m<d>;  # OUTPUT: «0␤» 
 
# only allow whole numbers 
my %m is Mix[Int= <a b b c c c>;
# Type check failed in binding; expected Int but got Str ("a")

运算符§

请参阅 具有集合语义的运算符,以获取适用于 Mix 等类型的“集合运算符”的完整列表。

示例

my $this-mix = (sugar => ⅓, spice => ¼, all-things-nice => ¾);
my $that-mix = ( sugar => 1spice => 2);
 
say $that-mix (<) $this-mix;     # OUTPUT: «True␤» 
say $that-mix (^) $this-mix;     # OUTPUT: «Set(all-things-nice)␤» 
say $that-mix (+) $this-mix;     # OUTPUT: «Bag(spice(2) sugar)␤» 
 
# Unicode versions: 
say $that-mix  $this-mix;     # OUTPUT: «True␤» 
say $that-mix  $this-mix;     # OUTPUT: «Set(all-things-nice)␤» 
say $that-mix  $this-mix;     # OUTPUT: «Bag(spice(2) sugar)␤» 

子 mix§

sub mix(*@args --> Mix)

@args 创建一个新的 Mix

方法§

方法 Bag§

method Bag (--> Bag:D)

强制 Mix 转换为 Bag。权重会转换为 Int,这意味着如果任何权重为负或截断为零,则结果 Bag 中键的数量可能少于原始 Mix 中的数量。

方法 BagHash§

method BagHash (--> BagHash:D)

强制 Mix 转换为 BagHash。权重会转换为 Int,这意味着如果任何权重为负或截断为零,则结果 BagHash 中键的数量可能少于原始 Mix 中的数量。

方法 reverse§

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

方法 total§

method total(Mix:D: --> Real)

返回所有权重的总和

say mix('a''b''c''a''a''d').total == 6;  # OUTPUT: «True␤» 
say %(=> 5.6=> 2.4).Mix.total == 8;          # OUTPUT: «True␤»

关于顺序的说明§

Bag/Mix 套件 中的其他元素相同,顺序不能得到保证或保持一致,你不应该依赖于诸如上面 reverse 之类的返回始终相同结果的方法。

另请参阅§

集合、包和混合

类型图§

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

展开上面的图表