2017-03-23 8 views
0

中の混合配列をソート私は次のようになり、ハッシュのいくつかのキーがあります。perlの

Test21 
Test1 
Test4 
Test2 
Test13 
TestA 
TestB 

私は作り付けのソート機能や余分なサブルーチンのいずれかを使用してそれらをソートするためにいくつかのアプローチを試みたが、私はしませんがそれが正しいと思われる。

私の所望の出力は次のようになります。

Test1 
Test2 
Test4 
Test13 
Test21 
TestA 
TestB 

私のアプローチの一つは、このように見えた:

#!/usr/bin/perl 

use strict; 
use warnings; 
use Data::Dumper qw(Dumper); 


my % hash = (Test1 => "Hello",Test21 => "Somedata", Test4 => "SomeMoreData",Test2 => "EvenMore",Test13 => "AlotMore",TestA => "Nope", TestB => "EvenMoreNope"); 

foreach my $keys(sort byNumberandAlpha keys %hash){ 
    print "$keys\n"; 
} 


sub byNumberandAlpha{ 

    my @temp_a = split("Test",$hash{$a}); 
    my $element_a = $temp_a[1]; 

    my @temp_b = split("Test",$hash{$b}); 
    my $element_b = $temp_b[1]; 

    if ($element_a =~ /[0-9]/ && $element_b =~ /[0-9]/) { 

     $a <=> $b; 

    }else{ 

     $a cmp $b; 
    } 
} 

OUTPUT:

Use of uninitialized value $element_a in pattern match (m//) at ExpirimentalSorting.pl line 23. 
Test1 
Test13 
Test2 
Test21 
Test4 
TestA 
TestB 

これは考え出したばかりの任意のヘルプ非常に高く評価されています。

+0

申し訳ありませんが、これは誤植でした。 – chrys

答えて

3

sortのものは、好きなように並べ替えることができます。挿入された比較に基づいて適切な値を返すことができます。

あなたのケースでは、「テストしていないビット」をソートし、数値的に最初に、アルファベット順に比較しているようです。

何ががやっている、とあなたのハッシュキーを探しています:

my @temp_a = split("Test",$hash{$a}); 

そして、それ...実際には動作しません、あなたの例のなし$hash{$a}単語を含まないため、 'テスト'。

だから、あなたは何か深遠なことを誤解していると思います。

私はあなたが欲しい考える

sub my_sort { 
    my ($a1) = $a =~ m/Test(\w+)/; 
    my ($b1) = $b =~ m/Test(\w+)/; 

    if ($a1 =~ /\d/ and $b1 =~ /\d/) { 
     return $a1 <=> $b1; 
    } 
    else { 
     return $a1 cmp $b1; 
    } 
} 

しかし、あなたはそれが単純まだSort::Naturally

foreach my $keys (nsort keys %hash) { 
    print "$keys\n"; 
} 

を使用することを見つけること(つまり、ソート種皮のTest1上にしていますが)。

dualvarを使用していくつかの魔法を実行することはできますが、それはちょっとしたワームです。しかし好奇心のために:

use Scalar::Util qw (dualvar); 
sub my_sort { 
    $_ = dualvar (s/\D+//r || 999999, $_) for $a, $b; 
    return ($a <=> $b 
     || $a cmp $b); 
} 

これは、あなたの「テキストのみ」の文字列の数値変換をオーバーロードすることにより、(番号は999999を超えない提供)尋ねた道をソートします。

したがって、Test1は期待通りに並べ替える(1、 "Test1")が含まれるdualvarになりますが、TestAはdualvar(999999、 "TestA")になります。しかし、2つがある場合は比較が「失敗」し、文字列の等価性に基づいて比較されます。

0と同じ場合(たとえば、$_ = dualvar (s/\D+//r || 0, $_) for $a, $b;)、TestATestBをもう一度並べ替えます。

+0

ありがとうございましたこれは私が探していたものでした。私は今私の間違いを理解していると思う。私は '$ hash {$ a}'でハッシュ値にアクセスしようとしていたので、 "Test"を含まない値でソートしようとしました。これは正しいです? – chrys

+1

あなたはハッシュの「値」でソートしようとしていました。 – Sobrique