2010/7/13

[Perl] sorting for array and hash

在用array跟hash的時候,有可能塞入各種不同的資料,而我們可能會需要針對array跟hash做排序的動作,在此就說明一些Perl有關排序的寫法。

假設你宣告一個array,裡面分別有1, 123, 12, 25, 2。

my @array = (1, 123, 12, 25, 2);

這時候我們可以利用sort來作排序。

print sort @array;

你認為會有怎樣的結果?你可能會認為@array會被排序成按數字大小排序的”1, 2, 12, 25, 123”,但是實際上結果會是”1, 12, 123, 2, 25”,這是因為sort在Perl裡面所預設的排序法是字典排序法(lexicographic order)。


那要怎樣才能做numeric order呢?Perl提供了靈活的方式,讓你可以自訂各種不同狀況的排序法。

# 字典排序
@sorted = sort @not_sorted;
@sorted = sort {$a cmp $b} @not_sorted;

# 反向排序
@sorted = reverse sort @not_sorted;
@sorted = sort {$b cmp $a} @not_sorted;

# 數字排序
@sorted = sort {$a <=> $b} @not_sorted;

# case-insensitive排序
@sorted = sort {lc $a cmp lc $b} @not_sorted;

# 字串長度排序
@sorted = sort {length $a <=> length $b} @not_sorted;

再不然你還可以將不同的排序法混著一起用。

# 先比字串長度, 再用字典法排序
@sorted = sort {length $a <=> length $b || $a cmp $b} @not_sorted;

再不然你也可以自己寫一種排序法來使用。

sub MySortingAlgorithm
{
$a =~ /^(\d+)\_.*\_([A-Za-z0-9]{2,}.*)$/;
my $a1 = $1;
my $a2 = $2;
$b =~ /^(\d+)\_.*\_([A-Za-z0-9]{2,}.*)$/;
my $b1 = $1;
my $b2 = $2;

$a1 <=> $b1 || $a2 cmp $b2
}

@sorted= sort MySortingAlgorithm @not_sorted;

如果你想排序的是一個hash,那麼你可以針對hash的key或value來作排序的動作。

# 按hash的key值排列
@sorted = sort { $a cmp $b } keys %hash; 

# 按hash的value排列
@sorted = sort { $hash{$a} cmp $hash{$b} } keys %hash; 

沒有留言:

張貼留言