2014-09-27 2 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

ответ

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, потому что нет объяснения того, что он делает. Они скопируют и вставляют ваш код, но ничего не узнают от него. –

+0

@ialarmedalien Надеюсь, что будут дополнительные вопросы, поэтому мне не нужно объяснять, что OP уже знаком. –

+2

Я восхищаюсь вашим оптимизмом, но я бы предположил, что многие новички не ищут дальнейшего объяснения, если они не понимают, что делает код - они скопируют его, а затем вернутся с похожими вопросами. Преобразования Шварца намного выше среднего новичка. –

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

Спасибо за ввод. Я изучу это. –

+0

Если возможно, не могли бы вы объяснить, что делают эти 2 строки? мой @sorted = {сортировать местный ($ а, $ Ь) = отображение {/^(? \ d +) \ S + (? . *) \ S (? \ D +)/х? {% +}: die "Невозможно разобрать $ _"} ($ a, $ b); ($ order ne 'name'? $ A -> {$ order} <=> $ b -> {$ order}: 0) || $ a -> {name} cmp $ b -> {name} } @array; –

+0

Использует [Именованные обратные ссылки] (http://perldoc.perl.org/perlretut.html#Named-backreferences), чтобы перевести значения в хэш его частей. Затем сравнивается на основе частей. – Miller

Смежные вопросы