class MixHash does Mixy { }

MixHash 是一个可变混合,这意味着一个没有特定顺序的不同元素的集合,每个元素都有一个分配给它们的实数权重。(对于不可变混合,请参阅 Mix。)

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

my $recipe = (butter => 0.22sugar => 0.1,
              flour => 0.275sugar => 0.02).MixHash;
 
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␤» 

MixHash 可以使用 { } 后缀运算符< > 后缀运算符(用于字符串文字键)作为对象哈希进行处理,该运算符返回混合元素的键的相应数字权重,对于不是元素的键返回 0。它还可以用于修改权重;将权重设置为 0 会自动从混合中删除该元素,将权重设置为非零数字会添加该元素(如果它不存在的话)

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

创建 MixHash 对象§

可以使用 MixHash.new 编写 MixHash。任何位置参数,无论其类型如何,都成为混合的元素 - 对于每次出现参数,其权重为 1

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

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

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

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

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

或使用伪装语法

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

运算符§

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

示例

my ($a$b= MixHash(2 => 24), MixHash(2 => 1.53 => 24);
 
say $a (<) $b;   # OUTPUT: «False␤» 
say $a (<=) $b;  # OUTPUT: «False␤» 
say $a (^) $b;   # OUTPUT: «MixHash(2(0.5) 3(2))␤» 
say $a (+) $b;   # OUTPUT: «MixHash(2(3.5) 4(2) 3(2))␤» 
 
# Unicode versions: 
say $a  $b;  # OUTPUT: «False␤» 
say $a  $b;  # OUTPUT: «False␤» 
say $a  $b;  # OUTPUT: «MixHash(2(0.5) 3(2))␤» 
say $a  $b;  # OUTPUT: «MixHash(2(3.5) 4(2) 3(2))␤» 

关于 reverse 和排序的说明。§

MixHash 从 Any 继承 reverse,但是,Mix 没有固有顺序,您不应该相信它会返回一致的输出。

如果您对 MixHash 进行排序,结果将是成对列表,此时 reverse 非常有意义

my $a = MixHash.new(221834);
say $a;  # OUTPUT: «MixHash(18 2(2) 3 4)␤» 
 
say $a.sort;  # OUTPUT: «(2 => 2 3 => 1 4 => 1 18 => 1)␤» 
say $a.sort.reverse;  # OUTPUT: «(18 => 1 4 => 1 3 => 1 2 => 2)␤» 

方法§

方法 Bag§

method Bag (--> Bag:D)

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

方法 BagHash§

method BagHash (--> BagHash:D)

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

另请参见§

集合、包和混合

类型图§

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

展开上方的图表