【问题标题】:Perl Array OrderPerl 数组顺序
【发布时间】:2015-01-17 23:11:48
【问题描述】:

我是 perl 新手,坚持以下练习。 我有一个多数组,并希望将其元素降序到内部数组总和。 我想用 Schwartzian 变换来排序。

这是我的矢量:

my @vectors = ( [1], [ 1, 2, 3 ], [4], [ 2, 2, 1 ] );

这是预期的向量:

@sorted_vectors = ( [1,2,3], [2,2,1], [4], [1] );

到目前为止,我已经尝试过这些:

(1) #!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my @vectors = ( [1], [ 1, 2, 3 ], [4], [ 2, 2, 1 ] );

my @sorted_vectors;

  # @sorted_vectors = ( [1,2,3], [2,2,1], [4], [1] );


my %hash=();
for(my $i=0;$i< scalar @vectors;$i++){

$hash{$i}=@vectors[$i];
}


for my $key ( sort { $hash{$b}[1] <=> $hash{$a}[1] } keys %hash ) {
    push(@sorted_vectors,[@{$hash{$key}}]);
}

 print Dumper( \@sorted_vectors );

(2)

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper;

my @vectors = ( [1], [ 1, 2, 3 ], [4], [ 2, 2, 1 ] );

my @sorted_vectors;

  # @sorted_vectors = ( [1,2,3], [2,2,1], [4], [1] );


my @sorted = map  { $_->[0] }
          sort { $a->[1] cmp $b->[1] }
          map  { [$_, foo($_)] }
               @vectors;

sub foo{
    my $res = 0;
    foreach my $x (@_) {
        $res+= $x;
    }
    return $res;

}

 print Dumper(\@sorted);

【问题讨论】:

  • 在比较数字时,您需要将 cmp 更改为 &lt;=&gt;cmp 仅在您的总数小于 10 时才有效。

标签: arrays perl sorting map


【解决方案1】:

您的代码只需少量改动即可工作,

my @sorted = map  { $_->[0] }
      # sort { $a->[1] cmp $b->[1] } # string sort, ascending order
      sort { $b->[1] <=> $a->[1] }   # numeric sort, descending order
      # map  { [$_, foo($_)] }       # foo() expects list, not array reference
      map  { [$_, foo(@$_)] }        # dereferencing $_ aref for foo()
           @vectors;

或相同的东西,但使用核心模块List::Util中的sum()

use List::Util 'sum';
my @vectors = ( [1], [ 1, 2, 3 ], [4], [ 2, 2, 1 ] );

my @sorted_vectors = map $_->[0],
    sort { $b->[1] <=> $a->[1] }
    map [ $_, sum(@$_) ],
    @vectors;

use Data::Dumper; print Dumper \@sorted_vectors;

输出

$VAR1 = [
      [
        1,
        2,
        3
      ],
      [
        2,
        2,
        1
      ],
      [
        4
      ],
      [
        1
      ]
    ];

【讨论】:

  • use List::Util 'sum'; my @sorted = sort { sum( @$b ) &lt;=&gt; sum( @$a ) } @vectors ;
  • @Zaid 是的,正确,请注意 OP 坚持使用 ST。
  • 另见List::UtilsBy::nsort_by,根据我的回答
  • @LeoNerd +1 遗憾的是,目前还没有将某种实用程序合并到核心中(一直想要 max_by,min_by)。
  • @mpapec:我在核心中维护 List::Util,因此我愿意接受有关迁移的建议。
【解决方案2】:

List::UtilsBy::rev_nsort_byList::Util::sum 很简单:

my @vectors = ( [1], [ 1, 2, 3 ], [4], [ 2, 2, 1 ] );

my @sorted = rev_nsort_by { sum @$_ } @vectors;

这会将@vectors 的列表按其控制块结果的相反数字顺序(即最大数字在前)排序。这里的控制块只是简单地将每个组件的所有单个元素相加。

【讨论】:

    猜你喜欢
    • 2017-08-08
    • 2012-08-27
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2016-09-06
    • 2017-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多