Tim*_*Tim 12
要按顺序获取sort
密钥,请在哈希的密钥上应用自定义排序功能.
my %hash = ( JANE => 1, jane => 2, JIM => 3, jim => 4 );
my @sorted_keys = sort {
lc $a cmp lc $b
|| $a cmp $b
} keys %hash;
Run Code Online (Sandbox Code Playgroud)
此自定义排序功能首先比较字符串,就好像它们是相同的情况一样,如果相等,则考虑大小写.
使用自定义排序,首先根据其较低的表示形式比较项目(以便"jane"的所有变体出现在"jim"的变体之前),然后通过执行默认的ASCII比较(其中大写字母在小写之前)来解析关系:
perl -e 'print join "\n", sort { lc $a cmp lc $b || $a cmp $b } qw( jim JANE jane JIM )'
Run Code Online (Sandbox Code Playgroud)
输出:
JANE
jane
JIM
jim
Run Code Online (Sandbox Code Playgroud)
尽管对于此操作看起来似乎有些过分,但标准的Unicode :: Collate和Unicode :: Collate :: Locale模块是针对此类操作而制作的.它们还按字母顺序对非ASCII数据进行排序,这是正常sort
情况下不会做的.
use utf8;
@names = qw[ jim JANE jane JIM josé josie Mary María mark ];
@sorts = sort @names;
Run Code Online (Sandbox Code Playgroud)
这给你的排序顺序
JANE JIM Mary María jane jim josie josé mark
Run Code Online (Sandbox Code Playgroud)
没有人想要的.这要好得多:
use utf8;
use Unicode::Collate;
@names = qw[ jim JANE jane JIM josé josie Mary María mark ];
$coll = new Unicode::Collate;
@sorts = $coll->sort(@names);
Run Code Online (Sandbox Code Playgroud)
那给了你
jane JANE jim JIM josé josie María mark Mary
Run Code Online (Sandbox Code Playgroud)
如果要在小写之前使用大写,请以这种方式指定:
use utf8;
use Unicode::Collate;
@names = qw[ jim JANE jane JIM josé josie Mary María mark ];
$coll = new Unicode::Collate upper_before_lower => 1;
@sorts = $coll->sort(@names);
print "@sorts\n";
Run Code Online (Sandbox Code Playgroud)
产量:
JANE jane JIM jim josé josie María mark Mary
Run Code Online (Sandbox Code Playgroud)
你可以cmp
按照习惯的方式在一对字符串上使用collation对象的方法,比如
#!/usr/bin/env perl
use 5.10.1;
use strict;
use autodie;
use warnings qw[ FATAL all ];
use utf8;
use open qw[ :std IO :utf8 ];
use Unicode::Collate;
my @names = qw[ fum fee fie foe ];
my $coll = Unicode::Collate->new;
my @sorts = $coll->sort(@names);
say "@names => @sorts\n";
for (
my($a, $b) = splice @names, 0, 2;
2 == grep {defined} $a, $b;
($a, $b) = ($b, shift @names)
)
{
given ($coll->cmp($a, $b)) {
when (-1) { say "$a < $b" }
when ( 0) { say "$a = $b" }
when (+1) { say "$a > $b" }
default { die "NOT REACHED" }
}
}
Run Code Online (Sandbox Code Playgroud)
产生:
fum fee fie foe => fee fie foe fum
fum > fee
fee < fie
fie < foe
Run Code Online (Sandbox Code Playgroud)
现在考虑这样的单词列表:
sát sot sät sét sæt ssét sat tot ßet SET set seat ?AT ?et saet SSET
Run Code Online (Sandbox Code Playgroud)
如果你对它运行默认排序,你几乎无用:
SET SSET saet sat seat set sot ssét sát sät sæt sét tot ßet ?AT ?et
Run Code Online (Sandbox Code Playgroud)
区分大小写的排序实际上并不是更好:
use utf8;
@names = qw[ sát sot sät sét sæt ssét sat tot ßet SET set seat ?AT ?et saet SSET ];
@sorts = sort {
lc $a cmp lc $b
||
$a cmp $b
} @names;
print "@sorts\n";
Run Code Online (Sandbox Code Playgroud)
产生仍然愚蠢的错误:
saet sat seat SET set sot SSET ssét sát sät sæt sét tot ßet ?AT ?et
Run Code Online (Sandbox Code Playgroud)
但这里是标准的Unicode排序:
use utf8;
use Unicode::Collate;
@names = qw[ sát sot sät sét sæt ssét sat tot ßet SET set seat ?AT ?et saet SSET ];
$coll = new Unicode::Collate upper_before_lower => 1;
@sorts = $coll->sort(@names);
print "@sorts\n";
Run Code Online (Sandbox Code Playgroud)
产生'correcter'(读:无限优先)版本:
saet sæt sät sat sát ?AT seat SET set sét ?et sot SSET ssét ßet tot
Run Code Online (Sandbox Code Playgroud)
Unicode :: Collate模块非常快,所以你不应该犹豫在你的路由字符排序需求上使用它.但有时候这还不够.那是因为不同的语言有不同的字母表思想.
顺便说一句,这些也是很好的例子,为什么" 有时硬编码[a-z]
到你的程序总是错误的."它充满了愚蠢甚至是侮辱性的假设. 请注意,除了最后三个之外的所有内容实际上都被认为是拉丁字母!这与我们在英语中使用的脚本相同.在代表英文文本,我已经不同了应对了解到,伊尼伊德,PO英尺,Laȝamon,简历,1ˢᵗ,MᶜKinley,凡Dijke,佳能市科罗拉多,酿酒,Dzur,角色,ⅷ,首映,比约恩,天真,合作, façade,café,Merððyn,archæology,甚至tschüß.重复口头禅:"硬编码[a-z]
到你的程序总是错的,有时候."说不!
Unicode :: Collate :: Locale模块处理本地排序约定.正如英语电话簿和书架有排序的名字特殊的方式,使不梅特您是否已经拼什么麦克布赖德或麦克布赖德,在德语世界排序他们的名字,使得韩德尔和亨德尔是相同的.这就是为什么没有变音符号,必须强制性地写über-为ueber-和超人的Uebermensch.区域设置排序知道这样做:
use utf8;
use Unicode::Collate::Locale;
@names = qw[ sát sot sät sét sæt ssét sat tot ßet SET set seat ?AT ?et saet SSET ];
$coll = new Unicode::Collate::Locale::
locale => de__phonebook,
upper_before_lower => 1,
;
@sorts = $coll->sort(@names);
print "@sorts\n";
Run Code Online (Sandbox Code Playgroud)
现在生产
saet sæt sät sat sát ?AT seat SET set sét ?et sot SSET ssét ßet tot
Run Code Online (Sandbox Code Playgroud)
与其他国家/地区的区域惯例有何不同,这是非常了不起的.在西班牙语语言环境("ES"),ñ是点之后,是信ñ之前Ò.这意味着正确的那种
raña rastrillo radio rana rápido ráfaga ranúnculo
Run Code Online (Sandbox Code Playgroud)
是
radio ráfaga rana raña ranúnculo rápido rastrillo
Run Code Online (Sandbox Code Playgroud)
用完全滚动的rr来说这些都非常快,以松开你的舌头.:)
"es__traditional"语言环境略有不同; 从历史上看,巧克力是在 西班牙语词典中以颜色出现的,与它在Enlgish中的作用方式不同.那是因为ch来自c之前和d之前,而ll来自l之前和m之前.这意味着这个序列:
lástima laña llama ligante
cidra caliente color chocolate con churros
pero pera Perú perro periglo peste
Run Code Online (Sandbox Code Playgroud)
排序到
caliente cidra color con chocolate churros
laña lástima ligante llama
pera periglo pero perro Perú peste
Run Code Online (Sandbox Code Playgroud)
尝试:
@list = ("jane","JIM","JANE","jim");
print sort { uc $a cmp uc $b or $a cmp $b } @list;
Run Code Online (Sandbox Code Playgroud)