2016-01-21 59 views
3

我正在嘗試學習Perl,並且我對它的瞭解可能還不到一週。在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 

感謝

UPDATE:

新輸入:

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
# 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"); 
} 
+0

謝謝!它完美的工作 – programnub

+0

我現在正在嘗試整理一個有更多列的列表,好像我只能對數量和ID進行排序。我也想改變我添加的列的值。我會非常感謝你,如果你能幫我或給我這個提示。 – programnub

+0

你是否甚至將額外的字段添加到數組?更新。 – ikegami

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