我已经在地图,tr和引用上阅读了教程和perldoc,但这个代码对于像我这样的初学者Perl用户来说有点太高级了.
print map $_->[1],
sort {
$a->[0] cmp $b->[0] ##first element of the array
or $a->[1] cmp $b->[1] }
map [ tr/"MATCH"/"MATCH"/, $_ ], @allmatches;
Run Code Online (Sandbox Code Playgroud)
所以我特别需要的是:$ _指的是什么(未定义?)
包括地图在内的最后一行做了什么?
我还不太了解$ a和$ b概念.他们指的是什么?@allmatches的第一个和下一个元素?
另外,所有逗号(在地图之后)做什么?如果这就像Schwartzian变换那么好,因为我还不明白,尽管阅读.
这是我的想法:将
未定义的标量映射为数组的引用(哪个?)同时调用第二个元素:[1].它首先根据"MATCH"的出现次数排序我的@allmatches数组,然后按字母表排序.通过参考的第二张地图对我来说很粗糙(地图在一步中做了很多); tr返回次数.第二个"MATCH"没用,但为什么呢?
额外奖励:有什么可以替换tr ///来排序更多,比如这是否可能:tr/MATCH#\ d + // ??
Nem*_*emo 14
从右到左阅读(即,按顺序执行)......
map [ tr/"MATCH"/"MATCH"/, $_ ], @allmatches;
Run Code Online (Sandbox Code Playgroud)
对于@allmatches的每个元素e,这将创建对双元素数组的引用,其中第一个元素是数字,第二个元素是e.映射的结果是这些引用的数组.
tr/"MATCH"/"MATCH"/计算字母M,A,T,C或H出现在e中的次数.(技术上用M代替M,用A代替A,用T代替T等,并计算它做了多少次这样的替换.)
实际上,它也在计算引号字符,因为tr ///将处理与其他任何字符相同的字符.这似乎是一个错误.
无论如何,假设每个引用引用一个数组[n,e],其中n是奇怪的数,e是@allmatches的原始元素.
然后"sort"对引用数组进行排序,主要由n(解释为字符串,而不是数字;这似乎是另一个错误),其次是字符串e.
最后,最外面的"map"在完成排序之后从每个双元素阵列中提取第二个元素(e).所以最终的结果就是对@allmatches的元素做一个奇怪的(我相信,错误的)排序.
[编辑:正如cjm在评论中指出的那样,这个map sort map成语被称为Schwartzian变换.]
tch*_*ist 10
不要从右到左阅读; 格式化它更好(原版是残酷的),然后从下到上阅读:
print map { $_->[1] }
sort {
$b->[0] <=> $a->[0]
||
$a->[1] cmp $b->[1]
}
map { [ tr/MATCH// => $_ ] }
@allmatches;
Run Code Online (Sandbox Code Playgroud)
或者使用更灵活的哈希代替:
print map { $_->{DATA} }
sort {
$b->{COUNT} <=> $a->{COUNT}
||
$a->{DATA} cmp $b->{DATA}
}
map {
+{
COUNT => tr/MATCH//,
DATA => $_,
}
} @allmatches;
Run Code Online (Sandbox Code Playgroud)
这当然与此相同:
print map { $$_{DATA} }
sort {
$$b{COUNT} <=> $$a{COUNT}
||
$$a{DATA} cmp $$b{DATA}
}
map {
+{
COUNT => tr/MATCH//,
DATA => $_,
}
} @allmatches;
Run Code Online (Sandbox Code Playgroud)
看看它有多好?另外,当您从下到上阅读它时,它对应于一个完全直截了当的shell风格的数据流:
map @allmatches | sort | map | print
Run Code Online (Sandbox Code Playgroud)
这比理解起来容易得多
print(map(sort(map @allmatches)))
Run Code Online (Sandbox Code Playgroud)
这就是为什么每个人都喜欢shell的数据流模型的原因.