perl - 对键包含非字母数字字符的哈希进行排序

标签 perl sorting hash natural-sort

我有一个像下面这样的哈希:

my %hash=( '(293 to 296)'   => 2,
           '(3118 to 3121)' => 2,
           '(330 to 333)'   => 2,
           '(2126 to 2129)' => 2,
           '(1999 to 2002)' => 2,
           '(2138 to 2141)' => 9,
           '(771 to 774)'   => 4,
           '(2016 to 2019)' => 1,
           '(888 to 891)'   => 5,
           '(3102 to 3105)' => 1,
        );

我想使用键对哈希进行排序,其中键包含括号。我试过下面的代码,

foreach $key(sort {$b <=> $a} keys %hash)
{
    print $key;
}

我得到了以下,未按数字排序:

(888 to 891)(2016 to 2019)(293 to 296)(3118 to 3121)(3102 to 3105)(330 to 333)(1999 to 2002)(2126 to 2129)(2138 to 2141)(771 to 774)

我希望得到一个按数字排序的输出,如下所示。请建议我实现以下目标的方法:

(293 to 296)
(330 to 333)
(771 to 774)
(888 to 891)
(1999 to 2002)
(2016 to 2019)
(2126 to 2129)
(2138 to 2141)
(3102 to 3105)
(3118 to 3121)                             

最佳答案

sort通过 $a 工作和 $b进入一个函数,并返回 -1 , 0+1 .

最简单的 - 按第一个数字排序 - 会这样:

sort { $a =~ s/.(\d+).*/$1/r <=> $b =~ s/.*(\d+).*/$1/r } keys %hash

这会从每个键中提取第一个数值,进行比较并返回该比较值。

当然,如果您的范围重叠,这将无法按照您想要的方式工作 - 您将不得不变得更复杂 - 如果您有:

100 到 200 150 至 180 120 到 205

它们应该如何排序?不管怎样——你写了一个在 $a 上“工作”的子程序。和 $b并进行比较。这里一个有用的技巧是“标准”排序运算符 - <=>cmp - 返回零,因此可以使用 || 进行快捷方式.

所以:

sub compare_numbers {
   my @a = $a =~ m/(\d+)/g;
   my @b = $b =~ m/(\d+)/g; 
   return ( $a[0] <=> $b[0] 
         || $a[1] <=> $b[1] )
}

如果第一个比较为零,则计算第二个比较。

或者你可以计算中间值:

sub compare_numbers {
   my @a = $a =~ m/(\d+)/g;
   my @b = $b =~ m/(\d+)/g; 
   return ( ($a[1] - $a[0] / 2 + $a[0]) <=> ($b[1] - $b[0] / 2 + $b[0])
}

您可以以与上述类似的方式使用其中任何一个:

sort compare_numbers keys %hash 

关于perl - 对键包含非字母数字字符的哈希进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34922327/

相关文章:

regex - perl 正则表达式来分隔文本中的每个字母

perl - 为什么 Perl 解析正则表达式

perl - 从哈希引用中获取值

python - 对数字和数组的列表进行排序?

javascript - 在javascript中按字母顺序对数组及其对象键进行排序

hadoop - 分区! hadoop是怎么做到的?使用哈希函数?默认功能是什么?

perl - 如何对哈希值进行 JSON 编码?

c - 为什么这对别人有效,对我却无效?

arrays - 如何将 ActiveRecord 结果转换为哈希数组

go - golang "undefined (type string has no field or method)"错误