简体   繁体   English

Perl 排序和正则表达式

[英]Perl sorting and regular expressions

I have an array that contains values like this:我有一个包含如下值的数组:

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

How would I use regular expressions in Perl to sort the entire array by year, item name, and price?我将如何在 Perl 中使用正则表达式按年份、项目名称和价格对整个数组进行排序? For example, if the user wants to sort by price they type 'price' and it sorts like this:例如,如果用户想按价格排序,他们输入“价格”,然后排序如下:

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

So far I've been able to sort by year like this:到目前为止,我已经能够像这样按年份排序:

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

/(\\d+) \\s+ (.+) \\s+ (\\S+)/x will match year name and price, /(\\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;

output输出

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

Using a sort without a transform:使用没有转换的排序:

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;

Outputs:输出:

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

Note: If one is sorting more than 10k items, efficiency might become a concern and one can utilize a https://en.wikipedia.org/wiki/Schwartzian_transform注意:如果要分拣超过 1 万个项目,效率可能会成为一个问题,可以使用https://en.wikipedia.org/wiki/Schwartzian_transform

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM