2014-09-27 20 views
0

我是Perl新手。比方说,我有一个包含这样的值的数组:Perl排序和正则表达式

 
@array = 
("2014 Computer Monitor 200", 
"2010 Keyboard 30", 
"2012 Keyboard 80", 
"2011 Study Desk 100"); 

我将如何使用Perl的正则表达式的一年,项目名称和价格对整个数组进行排序?例如,如果用户想通过价格排序他们输入“价格”,它排序是这样的:

 
    2010 Keyboard 30 
    2012 Keyboard 80 
    2011 Study Desk 100 
    2014 Computer Monitor 200 

到目前为止,我已经能够在今年这样的排序:

 
    @array = 
    ("2014 Computer Monitor 200", 
    "2010 Keyboard 30", 
    "2012 Keyboard 80", 
    "2011 Study Desk 100"); 

    $input = ; 

    chomp($input); 
    if ($input eq "year") 
    { 
     foreach $item (sort {$a cmp $b} @array) 
     { 
     print $item . "\n"; 
     } 
    } 
+1

你可以发布你写来尝试解决这样的代码? StackOverflow不是免费的编码服务。人们更愿意回答有关您的代码的问题,而不是为您编写或调试整个事情。 – chilemagic 2014-09-27 04:59:00

回答

2

/(\d+) \s+ (.+) \s+ (\S+)/x将匹配一年名称和价格,

use strict; 
use warnings; 

my $order = "price"; 
my @array = (
    "2014 Computer Monitor 200", 
    "2010 Keyboard 30", 
    "2012 Keyboard 80", 
    "2011 Study Desk 100" 
); 

my %sort_by = (
    year => sub { $a->{year} <=> $b->{year} }, 
    price => sub { $a->{price} <=> $b->{price} }, 
    name => sub { $a->{name} cmp $b->{name} }, 
); 
@array = sort { 

    local ($a, $b) = map { 
    my %h; 
    @h{qw(year name price)} = /(\d+) \s+ (.+) \s+ (\S+)/x; 
    \%h; 
    } ($a, $b); 
    $sort_by{$order}->(); 

} @array; 

# S. transform 
# @array = 
# map { $_->{line} } 
# sort { $sort_by{$order}->() } 
# map { 
# my %h = (line => $_); 
# @h{qw(year name price)} = /(\d+) \s+ (.+) \s+ (\S+)/x; 
# $h{name} ? \%h :(); 
# } @array; 

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

输出

$VAR1 = [ 
     '2010 Keyboard 30', 
     '2012 Keyboard 80', 
     '2011 Study Desk 100', 
     '2014 Computer Monitor 200' 
    ]; 
+0

你的回答对perl新手没有太大的帮助,因为没有解释它的作用。他们会复制和粘贴你的代码,但不会从中学到任何东西。 – 2014-09-27 08:00:22

+0

@ialarmedalien我希望会有更多的问题,所以我不必解释OP已经熟悉的事情。 – 2014-09-27 08:16:18

+2

我很佩服你的乐观,但我猜测很多新手如果不明白代码的作用,就不会寻找进一步的解释 - 他们会复制它,然后回来提出类似的问题。 Schwartzian变换超出了一般的新手。 – 2014-09-27 08:36:29

0

使用排序没有变换:

use strict; 
use warnings; 

my @array = ("2014 Computer Monitor 200", "2010 Keyboard 30", "2012 Keyboard 80", "2011 Study Desk 100"); 

my $order = "price"; 

my @sorted = sort { 
    local ($a, $b) = map { /^(?<year>\d+) \s+ (?<name>.*) \s (?<price>\d+)/x ? {%+} : die "Can't parse $_" } ($a, $b); 
    ($order ne 'name' ? $a->{$order} <=> $b->{$order} : 0) || $a->{name} cmp $b->{name} 
} @array; 

print "$_\n" for @sorted; 

输出:

2010 Keyboard 30 
2012 Keyboard 80 
2011 Study Desk 100 
2014 Computer Monitor 200 
+0

感谢您的意见。我会研究这个。 – 2014-09-28 02:58:28

+0

如果可能的话,你能解释一下这两条线在做什么吗? 我@sorted = {排序当地 ($ A,$ B)= {图/ ^(? \ d +)\ S +(?。*)\ S(? \ d +)/ X? {%+}:die“Can not parse $ _”}($ a,$ b); ($ order ne'name'?$ a - > {$ order} <=> $ b - > {$ order}:0)|| $ a - > {name} cmp $ b - > {name} } @array; – 2014-10-01 12:31:23

+0

使用[命名的反向引用](http://perldoc.perl.org/perlretut.html#Named-backreferences)将值转换为其部分的散列值。然后根据零件进行比较。 – Miller 2014-10-03 23:33:51