按模式匹配的Perl排序数组

时间:2015-08-09 21:49:57

标签: perl sorting

我想根据逗号

之后的值对此数组进行排序
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";
}

输出:

33.7687753, -84.3541355
33.7683870, -84.3559850
33.7645539, -84.3585973

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

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

2 个答案:

答案 0 :(得分:6)

看起来您可以使用Schwartzian transform。你有正确的想法:

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";
}

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

my @sorted_coords = map  { join ', ', @$_ }
                    sort { $b->[1] <=> $a->[1] }  
                    map  { [ split /, / ] }
                    @coords;

看起来比我原来的例子更容易描述和描述。

答案 1 :(得分:6)

很容易接受诱惑,使用花哨的实现而不是简单明了的东西。除非数据集很大,否则使用转换的速度优势可以忽略不计,并且代价是可读性大大降低

此处需要标准排序块

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;

输出

33.7687753, -84.3541355
33.7683870, -84.3559850
33.7645539, -84.3585973


更新

如果您愿意,可以使用正则表达式从输入记录中提取第二个字段。用这样的

替换map语句
my ($aa, $bb) = map /.*(\S+)/, $a, $b;

可以正常使用