Perl6 可以不区分大小写地 cmp 两个字符串吗?

Can Perl6 cmp two strings case insensitively?

我正在进行排序,希望将 alpha 值的 cmp 控制为不区分大小写(即 https://perl6.org/archive/rfc/143.html)。

可能有一些 :i 副词吗?

Perl 6 目前没有这个选项,但它是一种非常多变的语言,所以让我们添加它。

由于现有的 proto 不允许命名值,我们必须添加一个新的,或者写一个 only 子。
(也就是说,除了可选的 only 之外,您可以只使用下面的 multi。)

这只适用于词法,所以如果你写这篇文章,你可能想根据你正在做的事情将 proto/only 子标记为可导出。

proto sub infix:<leg> ( \a, \b, *% ){*}

multi sub infix:<leg> ( \a, \b, :ignore-case(:$i) ){
  $i

  ?? &CORE::infix:<leg>( fc(a) , fc(b) )
  !! &CORE::infix:<leg>(    a  ,    b  )
}
say 'a' leg 'A';     # More
say 'a' leg 'A' :i;  # Same
say 'a' leg 'A' :!i; # More

say 'a' leg 'A' :ignore-case; # Same

请注意 :$i:i( $i ) 的缩写,因此两个命名参数可以写为:
:ignore-case( :i( $i ) )

我还使用了 fc() 的子形式而不是 .fc 的方法形式,因为它允许使用字符串的本机形式而不会导致自动装箱。

来自documentation

In order to do case-insensitive comparison, you can use .fc (fold-case). The problem is that people tend to use .lc or .uc, and it does seem to work within the ASCII range, but fails on other characters. This is not just a Perl 6 trap, the same applies to other languages.

例如:

say ‘groß’.fc eq ‘GROSS’.fc; # ← RIGHT; True 

如果您正在使用正则表达式,则无需使用 .fc,您可以使用 :i (:ignorecase) 副词代替。

您可以通过代码块进行排序。如果块的元数为一,则在进行比较时它对两个元素都起作用。这是一个示例,显示了上一个答案中的 'fc'。

> my @a = <alpha BETA gamma DELTA>;
[alpha BETA gamma DELTA]
> @a.sort
(BETA DELTA alpha gamma)
> @a.sort(*.fc)
(alpha BETA DELTA gamma)

如果您想要 "dictionary" 排序顺序,@timotimo 在他们建议 collatecoll 进行排序时走在正确的轨道上。

对列表中的任何内容使用 collate() 对其进行排序。如果您需要自定义排序,请使用 coll 作为中缀运算符。

$ perl6
To exit tyype 'exit' or '^D'
> <a Zp zo zz ab 9 09 91 90>.collate();
(09 9 90 91 a ab zo Zp zz)
> <a Zp zo zz ab 9 09 91 90>.sort: * coll *;
(09 9 90 91 a ab zo Zp zz)