Perl6:将列表中的元素与另一个列表匹配

Ana*_*ant 5 perl6 raku

我有编号的列表大号.还有数另一份名单中号.我需要返回一个列表L"在发现号的两个 大号中号.

编辑:数学上,我正在寻找 Multiset交叉点.

例:

大号 = 3,14,15, 9,2,6
中号 = 9,7, ,,1 ,1 L" = 9,1,2,121

我为此编写了以下代码:

my @some-numbers = 3, 1, 4, 1, 5, 9, 2, 6;
my @to-match     = 9, 7, 1, 2, 1, 1;
my @matched;

my %histogram;
for @some-numbers -> $n { %histogram{$n}++ };

for @to-match -> $n {
    next if not defined %histogram{$n};
    if %histogram{$n} > 0 {
        push @matched, $n;
        %histogram{$n}--;
    }
};

say @matched;
Run Code Online (Sandbox Code Playgroud)

虽然它达到了目的,但我想知道是否有一种惯用的 Perl6方式吗?

一些背景:我一直在尝试一起学习Perl6和Python,并在两种语言中解决相同的难题.Python 为上述问题提供了一个特别令人满意的解决方案.至少对我的初学者来说:)

Cur*_*mes 6

你可以用袋子做:

my $some-numbers = bag 3, 1, 4, 1, 5, 9, 2, 6;
my $to-match     = bag 9, 7, 1, 2, 1, 1;
my $matched      = $some-numbers ? $to-match;
say $matched;
Run Code Online (Sandbox Code Playgroud)

输出:

bag(9, 1(2), 2)
Run Code Online (Sandbox Code Playgroud)

您可以将包转回到阵列中.kxxv.

my @match-list = $matched.kxxv;
say @match-list;
Run Code Online (Sandbox Code Playgroud)

输出:

[9 1 1 2]
Run Code Online (Sandbox Code Playgroud)

(如果您不关心重复,请使用集合代替行李.)

  • 对于任何遇到 Unicode 运算符问题的人,德克萨斯州版本的“∩”是“(&)” (2认同)

rai*_*iph 6

根据您正在寻找的精确语义,Bag操作可能只是票证:

my \L = 3, 1, 4, 1, 5, 9, 2, 6;
my \M = 9, 7, 1, 2, 1, 1;

.put with L.Bag ? M.Bag;
Run Code Online (Sandbox Code Playgroud)

显示:

9 1(2) 2
Run Code Online (Sandbox Code Playgroud)

这是a的字符串化Bag含三个 '9','1''2'其相应的(重复计数)是整数1,21.

要让Perl 6从包中生成一个列表,每个键重复其关联值指示的次数,请使用以下.kxxv方法:

.kxxv.put with L.Bag ? M.Bag;
Run Code Online (Sandbox Code Playgroud)

显示:

9 1 1 2
Run Code Online (Sandbox Code Playgroud)

(该kxxv方法的助记符是它k用于"键"然后xxxx重复运算符类似,最后v用于"值".如果你考虑它,它就是有意义的.)

但也许一袋不会.例如,结果中元素的顺序可能很重要 - 你需要9 1 2 1而不是9 1 1 2吗?如果包包不是正确的方法,我会延长这个答案.