如何在不使用Perl中的$ b(比较)$ a的情况下对一个键升序进行排序,另一个降序排序?

时间:2012-02-22 16:26:14

标签: perl sorting perl-critic

在Perl中,我可以这样做:

my @unit_indices = sort { 
    $units{$b}[0] <=> $units{$a}[0] 
        or
    $a cmp $b
} keys %units;

按一个字段(数组元素)降序排序,另一个(散列键)升序排序,但导致perlcritic抱怨:

  

禁止在第X行第Y列的排序块$ a之前的$ b。参见PBP的第152页。 (严重程度:1)

Perl最佳做法建议改为使用reverse

  

但如果你写的话,操作会更容易理解:
      @sorted_results =反向排序@unsorted_results;

但是,我还没有找到一种让方向相反的方法。

显然,我可以告诉perlcritic忽略这一点,但我想知道如何完成我需要的工作并使perlcritic满意。

3 个答案:

答案 0 :(得分:9)

Perl ::批评者有时更关心的是准确复制PBP而不是提出良好的政策,而且一些 Perl最佳实践并未老化。例如,现在可悲的过时Miscellanea::RequireRcsKeywords默认仍处于启用状态。

Perl :: Critic的政策不应被视为佳能。他们缺乏进行主观分析的能力来决定“修复”是否实际上会增加复杂性,特别是当严重程度下降且收益变得更窄和更窄时。 BuiltinFunctions::ProhibitReverseSortBlock是一种“整容”级政策,完全属于这一类。

虽然有人可能会跳过$b cmp $a并向后阅读,但是一旦正确看待就不难理解,不值得在之后反转整个数组的开销,并且肯定不值得对你的排序块进行扭曲符合政策分析的局限性。他们决定不改变默认行为以将策略限制为简单排序块是IMO不正确的。您的排序块显然超出了书面策略的范围,只是因为Perl :: Critic的策略实现有限而被触发。

仅仅因为Perl :: Critic默认情况下有一个政策并不意味着它们代表了良好的做法,也不应该盲目地遵循它们。随意配置它符合您项目的品味,以最挑剔的级别运行Perl :: Critic需要它。为了防止使percritic成为一种习惯性的东西,我建议在.perlcritic中选择逐项逐项的项目范围的政策决定。

请记住,重点不在于小写快乐,重点是编写更好的代码。

答案 1 :(得分:4)

我同意tchrist的评论,但是从表面上看你的问题:

1)使用## no critic

my @unit_indices = sort {   ## no critic (ReverseSortBlock)
    $units{$b}[0] <=> $units{$a}[0] 
        or
    $a cmp $b
} keys %units;

2)使用.perlcriticrc文件

[-BuiltinFunctions::ProhibitReverseSortBlock]

3)改变你的比较感

my @unit_indices = sort { 
    -($units{$a}[0] <=> $units{$b}[0])
        or
    $a cmp $b
} keys %units;

my @unit_indices = sort { 
    -$units{$a}[0] <=> -$units{$b}[0])
        or
    $a cmp $b
} keys %units;

答案 2 :(得分:2)

随意使用perlcritic,但不要成为它的奴隶。 perlcritic的全部意义在于能够发出很有可能出错的警告。

肯定会尝试鼓励使用reverse sort { $a <=> $b }而不是sort { $b <=> $a },但这不能在这里完成。

不要让你的代码变得更糟,以免发出虚假警告。有时,警告是错误的,在这种情况下你应该解决警告。