按模式匹配的Perl排序数组

Ear*_*ome 3 sorting perl

我想根据逗号后的值对此数组进行排序

my @coords;
$coords[0] = "33.7645539, -84.3585973";
$coords[1] = "33.7683870, -84.3559850";
$coords[2] = "33.7687753, -84.3541355";

foreach my $coord (@sorted_coords) {
    print "$coord\n";
}
Run Code Online (Sandbox Code Playgroud)

输出:

33.7687753, -84.3541355
33.7683870, -84.3559850
33.7645539, -84.3585973
Run Code Online (Sandbox Code Playgroud)

我曾考虑使用map,grep和capture groups作为列表输入sort,但我还没有走得太远:

my @sorted_coords = sort { $a <=> $b } map {$_ =~ /, (-*\d+\.\d+)/} @unique_coords;

Bor*_*din 7

很容易屈服于使用花哨的实现而不是简单明了的诱惑.除非数据集很大,否则使用变换的速度优势可以忽略不计,并且以降低易读性为代价

标准排序块就是这里所需要的

use strict;
use warnings;

my @coords = (
    "33.7645539, -84.3585973",
    "33.7683870, -84.3559850",
    "33.7687753, -84.3541355",
);

my @sorted_coords = sort {
    my ($aa, $bb) = map { (split)[1] } $a, $b;
    $bb <=> $aa;
} @coords;


print "$_\n" for @sorted_coords;
Run Code Online (Sandbox Code Playgroud)

产量

33.7687753, -84.3541355
33.7683870, -84.3559850
33.7645539, -84.3585973
Run Code Online (Sandbox Code Playgroud)



更新

如果您愿意,可以使用正则表达式从输入记录中提取第二个字段.map用这样的东西替换语句

my ($aa, $bb) = map /.*(\S+)/, $a, $b;
Run Code Online (Sandbox Code Playgroud)

会很好的


Jim*_*vis 6

看起来你可以使用Schwartzian变换.你有正确的想法:

my @coords;
$coords[1] = "33.7683870, -84.3559850";
$coords[2] = "33.7687753, -84.3541355";
$coords[0] = "33.7645539, -84.3585973";

my @sorted_coords = map  { $_->[0] }              # 3. extract the first element
                    sort { $b->[1] <=> $a->[1] }  # 2. sort on the second
                                                  #    element, descending
                    map  { [ $_, /,\s*(\S+)$/ ] } # 1. create list of array refs
                    @coords;

foreach my $coord (@sorted_coords) {
    print "$coord\n";
}
Run Code Online (Sandbox Code Playgroud)

编辑:添加约书亚的建议:

my @sorted_coords = map  { join ', ', @$_ }
                    sort { $b->[1] <=> $a->[1] }  
                    map  { [ split /, / ] }
                    @coords;
Run Code Online (Sandbox Code Playgroud)

看起来比我原来的例子更容易看起来更具描述性.

  • 我唯一要改变的是换掉相对昂贵的正则表达式捕获而不是:`map {[$ _,(split',')[1]]} (2认同)