perl - 在保持顺序的同时按值长度对哈希进行排序
问题描述
我目前正在编写一个 Perl 脚本来对标准输入中的行进行排序并按行长的顺序打印这些行,同时保留相等的行的顺序。我的排序代码包括以下内容:
while (my $curr_line = <STDIN>) {
chomp($curr_line);
$lines{$curr_line} = length $curr_line;
}
for my $line (sort{ $lines{$a} <=> $lines{$b} } keys %lines){
print $line, "\n";
}
例如,我的标准输入由以下内容组成:
tiny line
medium line
big line
huge line
rand line
megahugegigantic line
我会得到以下输出:
big line
rand line
tiny line
huge line
medium line
megahugegigantic line
有什么办法可以保留等长线的顺序,以便小号出现在大号之前,然后大号出现在兰特之前?此外,每次我运行脚本时,顺序似乎都会发生变化。
提前致谢
解决方案
一种可能的解决方案
您可以将行的位置保存在输入文件句柄以及length
. 魔术$.
变量(输入行号)提供了这一点。然后,您可以对这两个值进行排序。
use strict;
use warnings;
my %lines;
while ( my $curr_line = <DATA> ) {
chomp($curr_line);
$lines{$curr_line} = [ length $curr_line, $. ];
}
for my $line (
sort {
$lines{$a}->[0] <=> $lines{$b}->[0]
|| $lines{$a}->[1] <=> $lines{$b}->[1]
} keys %lines
) {
print $line, "\n";
}
__DATA__
tiny lin1
medium line
big line
huge lin2
rand lin3
megahugegigantic line
这将始终输出
big line
tiny lin1
huge lin2
rand lin3
medium line
megahugegigantic line
当然,您也可以使用散列来使代码更具可读性。
$lines{$curr_line} = {
length => length $curr_line,
position => $.,
};
您的实施说明
由于随机哈希排序,您的结果每次都会更改顺序。keys
由于 Perl 实现散列的方式,返回键列表的方式是随机的。这是设计使然,并且是一项安全功能。由于存在多个具有相同值的键,因此排序有时会返回不同的结果,具体取决于哪个相等值的键首先出现。
你可以通过在你的电话sort
前面加上另一个来缓解这种情况。keys
这将按名称对键进行排序,至少使不需要的结果的顺序保持一致。
# vvvv
for my $line (sort{ $lines{$a} <=> $lines{$b} } sort keys %lines) { ... }
请注意,chomp
如果您\n
在print
. 无论如何,它总是相同的长度。如果这样做,您应该print
使用$/
,这是删除的输入记录分隔符,chomp
否则您会伪造数据。
推荐阅读
- python - 循环在 twitter 上搜索列表的各种元素
- python - 我需要帮助使用此代码打印阿拉伯语单词
- html - 2 如何发布图形/图像/绘图 - 除了 .JPEG 之外还有哪些文件格式 - 例如 ?.bmp、?.TIFF ?. 东风?有很多
- reactjs - 访问反应网络应用程序时,整个反应库会在第一个请求中传输到我的浏览器吗?
- angular - Angular 11 '错误 NG2007:类正在使用 Angular 功能,但未装饰。' 但是班级是装饰的
- c++ - 表达式必须有常数值错误
- linux - bash - 给文件中的每个字符随机颜色
- c# - 使用 WinUI 3 (Project Reunion) 开发应用程序时,有没有办法将应用程序设置为全屏模式?
- linux - 如何使用 mutt 重新发送退回的电子邮件
- python - 使用 python 替换 Yaml 文件中的字符串