在Perl中对名称列表进行排序

时间:2016-01-21 01:53:50

标签: database perl list sorting numbers

我正在尝试学习Perl,而且我可能不到一周就相当新。

我想对名单列表进行排序(在这种情况下是水果)并给他们一个ID。我的脚本目前为他们提供ID,但我也想对它们进行排序。

当前代码:

use strict;
use warnings;

my %unique;

open(my $inFile, $ARGV[0]) || die "Could not open file '$ARGV[0]' $!";
open(my $outFile, ">$ARGV[1]") || die "Could not find file '>$ARGV[1]' $!";

while (<$inFile>) {
        my @fields = split;

        my $fruit  = $fields[0];
        my $quantity   = $fields[1];

        my @parts = split(/[_.]/, $fruit);
        my $counter = ++$unique{$parts[1]}{$parts[2]};

        print $outFile join("\t", $fruit, $quantity, "$fruit.$counter"), "\n";
}

输入:

Apple   3
Apple   50
Apple   1
Orange  51
Orange  21

当前输出:

Apple   3   Apple.1
Apple   50  Apple.2
Apple   1   Apple.3
Orange  51  Orange.1
Orange  21  Orange.2

通缉输出:

Apple   1   Apple.1
Apple   3   Apple.2
Apple   50  Apple.3
Orange  21  Orange.1
Orange  51  Orange.2

Apple   3   Apple.2
Apple   50  Apple.3
Apple   1   Apple.1
Orange  51  Orange.2
Orange  21  Orange.1

由于

更新:

新输入:

Apple   3   1
Apple   50  2
Apple   1   3
Orange  51  3
Orange  21  5

通缉输出

Apple   1   3   Apple.1
Apple   3   1   Apple.2
Apple   50  2   Apple.3
Orange  21  5   Orange.1
Orange  51  3   Orange.2

3 个答案:

答案 0 :(得分:3)

# Read in the data
my @data;
while (<>) {
   chomp;
   push @data, [ split(/\t/, $_, -1) ];
}

# Sort it
@data = sort {
   $a->[0] cmp $b->[0]   # By name
      ||
   $a->[1] <=> $b->[1]   # By quantity
} @data;

# Generate the ids and output the data.
my %counts;
for my $row (@data) {
   my $id = join('.', $row->[0], ++$counts{ $row->[0] });
   push @$row, $id;
   print(join("\t", @$row), "\n");
}

答案 1 :(得分:2)

这是一个使用几个CPAN模块(Sort::Key::MultiDDP)的解决方案。

#!perl -l
use Sort::Key::Multi 'sii_keysort' ;

my @mungeddata = sii_keysort { chomp ; split /\s+/ , $_ }  <DATA> ;

use DDP;
p @mungeddata ;

__DATA__
Apple    3    1
Apple    50   2
Apple    1    3
Orange   51   3
Orange   21   5

<强>输出:

[
    [0] "Apple    1    3",
    [1] "Apple    3    1",
    [2] "Apple    50   2",
    [3] "Orange   21   5",
    [4] "Orange   51   3"
] 

答案 2 :(得分:0)

试试这个

# Read in the data
my @data;
while (<>) {
   chomp;
   push @data, [ split(/\t/, $_, -1) ];
}

# Sort it
@data = sort {
   $a->[0] cmp $b->[0]   # By name
      ||
   $a->[1] <=> $b->[1]   # By quantity
} @data;

# Generate the ids and output the data.
my %counts;
for my $row (@data) {
   my $id = join('.', $row->[0], ++$counts{ $row->[0] });
   push @$row, $id;
   print(join("\t", @$row), "\n");
}