我想匹配任意一组单词,但是失败了,请问怎样才能正确地匹配到?
my @a=<a b c d e f>;
my $x="a1234567";
say $x ~~ m/ @a.any /;
Answer
my @a = <a b c d e f>;
my $x = "a1234567";
say $x ~~ /@a/
/@a/
和 /| @a/
相同,它是最长的备选分支。对于备选分支,你可以使用 /|| @a/
。
sub foo($x) {
$x**2
}
my $alist = (1,2, &foo ... ^ * > 100);
我想得到 (1 4 9 16 25 .. )
而程序得到的是 (1 2 4 16 256)
。
Answer:
my @a = (1..*).map(* ** 2); # using a Whatever-expression
my @a = (1..*).map(&foo); # using your `foo` function
或者使用 Haskell/Python 那样的列表解析式:
my @a = ($_ ** 2 for 1..*); # using an in-line expression
my @a = (foo $_ for 1..*); # using your `foo` function
另外还有一种方法:
my @alist = {(++$)²} ... * > 70; # stop immediately after past 70
say @alist; # [1 4 9 16 25 36 49 64 81]
my @alist = {(++$)²} ...^ * > 70; # stop immediately before past 70
say @alist; # [1 4 9 16 25 36 49 64]
个人不推荐使用 $
匿名变量的这种写法, 对于 new comer 不太友好。
Is it possible to use junction to match any of the values in a junction? I want to match any of the values in an array. What is the proper way to do it?
> my @a=<a b c>
[a b c]
> any(@a)
any(a, b, c)
> my $x=any(@a)
any(a, b, c)
> my $y = "a 1"
a 1
> say $y ~~ m/ $x /
False
> say $y ~~ m/ "$x" /
False
> my $x = any(@a).Str
any("a", "b", "c")
> say $y ~~ m/ $x /
False
> say $y ~~ m/ || $x /
False
> say $y ~~ m/ || @a /
「a」
Answer
junctions
不该被插值到正则表达式中。它们应该被用在普通的 Perl 6 表达式中,特别是带有比较操作符的表达式(例如 eq
):
my @a = <x y z>;
say "y" eq any(@a); # any(False, True, False)
say so "y" eq any(@a); # True
要在正则表达式中匹配一个数组的任意值,就在正则表达式中写上那个数组名好了(以@
开头)。默认地,这被插值为 |
备选分支(“longest match”),但是你也可以把他指定为 ||
备选分支(“first match”)。
my @a = <foo bar barkeep>;
say "barkeeper" ~~ / @a /; # 「barkeep」
say "barkeeper" ~~ / || @a /; # 「bar」
我需要排序数组的数组, .sort
方法能不能按照内层数组的不同索引来排序呢?
要排序的数组在一个更大的数组的外面:(birthday 是 ‘mmddyy’ 格式的:)
my @allRecords = [ [birthday1 firstName1 lastName1 [data1]
[birthday2 firstName2 lastName2 [data2]
...
[birthdayN firstNameN lastNameN [dataN] ];
@allRecords.sort by itself sorts by birthdays.
有什么好方法能按照 firstName 或 lastName 或 按照内层数组里面的数据来排序?
Answer
sort
方法接受一个可选的 sub 参数。如果元数是 1, 那么它使用返回值作为比较操作数;如果元数为 2, 那么你可以在两个元素之间手动作比较,两个元素的比较会返回 Less
, Same
, More
。
拿你上面的例子来说,我们可以像这样按照 first name 进行排序:
@allRecords.sort(*.[1])
我们可以先按照 last name 再按照 first name 进行排序,然后按照 birthday 来做单独的比较,就像这样:
@allRecords.sort(-> $a,$b {
$a[2] cmp $b[2] || $a[1] cmp $b[1] || $a[0] cmp $b[0]
});
或者再次通过转换操作数:
@allRecords.sort(*.[2...0]);
变换 birthday 条目以至于我们能先按照 year 排序作为练习留给读者完成,但是其中一种方法是在合适的地方添加像这样的代码:
.comb(2).list.rotate(-1).join
你可以按照 lastname,firstname, birthday 这样的顺序排序:
@a.sort: *[2...0]
还有两个问题:
-
*.[1]
和*[1]
有什么区别?
两者没有任何区别,但是前者可读性更好!
- range 操作符和 … 序列操作符有什么区别
range 不能倒数, ...
可以倒数。
在 Perl 6 中怎样找出列表中最大值的索引?
Answer
my @list = 1,2,9,6,9,5;
@list.maxpairs; # [2 => 9 4 => 9]
@list.maxpairs
用于获取索引和对应最大值的所有对儿。
@list.pairs.max(*.value).key
用于仅获取单个索引。
> @list.pairs.max(*.value).key
2
如何彻底地展平 Perl 6 的列表?这个问题不同于 How do I “flatten” a list of lists in perl 6?, 后者不是彻底的 flat。
my @a = 'a', ('b', 'c' );
my @b = ('d',), 'e', 'f', @a;
my @c = 'x', $( 'y', 'z' ), 'w';
my @ab = @a, @b, @c;
say "ab: ", @ab;
my @f = @ab;
@f = gather {
while @f {
@f[0].elems == 1 ??
take @f.shift.Slip
!!
@f.unshift( @f.shift.Slip )
}
}
say "f: ", @f;
这打印出:
ab: [[a (b c)] [(d) e f [a (b c)]] [x (y z) w]]
f: [a b c d e f a b c x y z w]
但这不够简洁。一种可行的办法是使用:gather/take/deepmap
:
say gather @ab.deepmap(*.take)
postcircumfix []
操作符可用于多维下标来获取一组展平的叶子节点,直到特定的深度,尽管 “无限深度” 版本还没有实现:
say @ab[*;*]; # (a (b c) (d) e f [a (b c)] x (y z) w)
say @ab[*;*;*]; # (a b c d e f a (b c) x y z w)
say @ab[*;*;*;*]; # (a b c d e f a b c x y z w)
say @ab[**]; # HyperWhatever in array index not yet implemented. Sorry.
- 避免容器化 (containerization)
内置的 flat
函数能很好地展平深度嵌套的列表。问题是它不能落进 item 容器(Scalar)中。嵌套列表中非故意的 item 容器的常见来源有:
-
数组
(但不是列表
)将其每个元素包装在一个新的 item 容器中,无论它之前有没有。 - 如何避免:如果不需要 Array 提供的可变性,请使用列表的列表而不是数组的数组。使用绑定
:=
可以用来代替赋值,将列表存储在@变量中,而不将其转换为数组
:
my @a := 'a', ('b', 'c' );
my @b := ('d',), 'e', 'f', @a;
say flat @b; # (d e f a b c)
- $variables 是 item 容器。
- 如何避免:当将列表存储在
$
变量中,然后将其作为元素插入到另一个列表中时,使用<>
来对它进行 decontainerize(解容器化)。当把$
变量传递给 flat 时, 父列表的容器也可以使用|
绕过:
my $a = (3, 4, 5);
my $b = (1, 2, $a<>, 6);
say flat |$b; # (1 2 3 4 5 6)
未完待续。。。