【问题标题】:How can I sort a hash's keys naturally?如何自然地对哈希的键进行排序?
【发布时间】:2008-12-20 17:47:03
【问题描述】:

我有一个 Perl 哈希,其键以数字开头,或者是数字。

如果我使用,

foreach my $key (sort keys %hash) {
    print $hash{$key} . "\n";
}

列表可能会出现,

0
0001
1000
203
23

代替

0
0001
23
203
1000

【问题讨论】:

  • 不应该是 print $key 列出键吗?
  • 您正在对键进行排序,但您正在打印哈希值...
  • 我建议您查找“自然排序”。 Paul Tomblin 下面选择的答案对于“自然”排序算法是绝对不正确的。

标签: perl sorting hash natural-sort


【解决方案1】:
foreach my $key (sort { $a <=> $b} keys %hash) {
    print $hash{$key} . "\n";
}

排序操作采用可选的比较“子程序”(可以是代码块,就像我在这里所做的那样,或者是子程序的名称)。我提供了一个内联比较,它使用内置的数字比较运算符“”将键视为数字。

【讨论】:

  • 澄清一下:您的情况下的键是字符串,并按字符串排序。 运算符将其参数解释为数字,根据需要将字符串转换为数字。这就是 perl 的奇怪之处:在 perl 中输入的是运算符,而不是变量。
  • 这是上下文而不是类型。 在数字上下文中评估它的操作数,而默认排序运算符 (cmp) 在标量(即字符串)上下文中评估它们。
  • @kixx:数字也是标量。标量是单个值,与类型无关。也就是说,数字、字符串,甚至引用都是标量,而列表和散列则不是。 “标量上下文”与此几乎没有关系。
  • 我认为这个答案有点误导。当然,它适用于数字。但这是因为&lt;=&gt; 运算符按数字方式 进行排序。这不适用于单词(“参数在数字比较中不是数字”)。 cmp 运算符按 lexically 排序,但请参阅 Schwern 的答案以了解实际排序 naturally 的内容。
  • @Paul Tomblin:不是真的:Argument "123foo" isn't numeric。这对我来说不是“很好”。
【解决方案2】:

Paul's answer 对数字是正确的,但如果你想更进一步,像人类一样对混合的单词和数字进行排序,cmp&lt;=&gt; 都不会。例如,

  9x
  14
  foo
  fooa
  foolio
  Foolio
  foo12
  foo12a
  Foo12a
  foo12z
  foo13a

Sort::Naturally 解决了这个问题,提供了nsortncmp 例程。

【讨论】:

    【解决方案3】:

    您的第一个问题是循环体(这里似乎没有其他答案指出)。

    foreach my $key ( sort keys %hash ) {
        print $hash{$key} . "\n";
    }
    

    我们不知道%hash 的键是什么。我们只知道在循环内按词汇顺序以$key 的形式交给您的它们。然后,您可以使用密钥访问散列的内容,打印每个条目。

    散列的不是按排序顺序出来的,因为你是按排序的。

    您是否希望按排序顺序输出 ,请考虑以下循环:

    foreach my $value ( sort values(%hash) ) {
        printf( "%s\n", $value );
    }
    

    此循环确实按照您观察到的顺序打印值:

    0
    0001
    1000
    203
    23
    

    要对它们进行数字排序,请使用

    foreach my $value ( sort { $a <=> $b } values(%hash) ) {
        printf( "%s\n", $value );
    }
    

    这会产生

    0
    0001
    23
    203
    1000
    

    这就是你想要的。

    有关更多信息和更多示例,请参阅the Perl manual for the sort function

    【讨论】:

      【解决方案4】:
      $key (sort { $a <=> $b} keys %hash) 
      

      会成功的

      或降序排序:

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

      甚至

      $key (sort { $a <=> $b} values %hash)
      $key (sort { $b <=> $a} values %hash)
      

      【讨论】:

      • 最后一个会做什么?按值而不是键排序?如果值不是唯一的怎么办?排序不稳定?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 2012-03-07
      • 1970-01-01
      相关资源
      最近更新 更多