Karle: Fieser sort

Hi,

ich hab hier einen fiesen sort vor mir und bekomme es nicht hin.
Ausgangslage ist ein ein HoA.

<key>: value1 value2 ...  
a: name1 neuername1/12  
b: name1 neuername2/23  
c: name1 neuername1/1  
d: name10 neuername1/1  
e: name2 neuername1/3

So und nun hätte ich das gerne so sortiert bzw. meinen print:

name1 neuername1/1 ...  
name1 neuername1/12 ...  
name1 neuername2/23 ...  
name2 neuername1/3 ...  
name10 neuername1/1 ...

Also die Sortierreihenfolge ist - erst value1 alphabetisch(und wenn möglich die Zahl numerisch) und dann value2 ebenfalls so. Der Key ist mir egal.

Ich hab mir als Anregung http://perldoc.perl.org/perldsc.html#Access-and-Printing-of-a-HASH-OF-ARRAYS angeschaut, aber verstehe es schlicht nicht bzw. kann es nicht umsetzen für meinen Fall.

Gruss
Karle

  1. 你好 Karle,

    <key>: value1 value2 ...

    a: name1 neuername1/12
    b: name1 neuername2/23
    c: name1 neuername1/1
    d: name10 neuername1/1
    e: name2 neuername1/3

    
    >   
    > So und nun hätte ich das gerne so sortiert bzw. meinen print:  
    >   
    > ~~~perl
    
    name1 neuername1/1 ...  
    
    > name1 neuername1/12 ...  
    > name1 neuername2/23 ...  
    > name2 neuername1/3 ...  
    > name10 neuername1/1 ...
    
    

    Also die Sortierreihenfolge ist - erst value1 alphabetisch(und wenn möglich die Zahl numerisch) und dann value2 ebenfalls so. Der Key ist mir egal.

    Da sort einen Block als Sortier-Kriterium erlaubt, kannst du das doch mit beliebig komplexem Code umsetzen. Ein Ansatz wäre:

    use strict;  
    use Data::Dumper;  
      
    sub get_parts;  
      
    my $data = {  
      a => ['name1', 'neuername1/12'],  
      b => ['name1', 'neuername2/23'],  
      c => ['name1', 'neuername1/1'],  
      d => ['name10', 'neuername1/1'],  
      e => ['name2', 'neuername1/3']  
    };  
      
    my @sorted_keys = sort {  
      my ($charpart_a,$digitpart_a) = get_parts($data->{$a}->[0]);  
      my ($charpart_b,$digitpart_b) = get_parts($data->{$b}->[0]);  
      
      if($charpart_a eq $charpart_b) {  
        if($digitpart_a == $digitpart_b) {  
          my ($charpart_a,$digitpart_a,$digitpart2_a) = get_parts($data->{$a}->[1]);  
          my ($charpart_b,$digitpart_b,$digitpart2_b) = get_parts($data->{$b}->[1]);  
      
          if($charpart_a eq $charpart_b) {  
            if($digitpart_a == $digitpart_b) {  
              $digitpart2_a <=> $digitpart2_b;  
            }  
            else {  
              $digitpart_a <=> $digitpart_b;  
            }  
          }  
          else {  
            $charpart_a cmp $charpart_b;  
          }  
        }  
        else {  
          $digitpart_a <=> $digitpart_b;  
        }  
      }  
      else {  
        $charpart_a cmp $charpart_b;  
      }  
      
    } keys %$data;  
      
      
    print join(", ",@sorted_keys),"\n";  
      
    sub get_parts {  
      $_[0] =~ /^(\w+)(\d+)(?:\/(\d+))?$/;  
      
      return ($1,int($2),$3);  
    }  
      
    # eof
    

    再见,
     克里斯蒂安

    --
    http://wwwtech.de/
    IRC-Clients und Irssi-Scripting | Flyspray
    <Tim> Ich bin nicht hier, um zu helfen. Mir hilft ja auch keiner. Sogar mein Brötchen muss ich mir jetzt selber schmieren.
    1. Hi,

      Danke für den Post ... ich muss da erstmal versuchen durchzublicken was du da machst - aber bin dran, zwar langsam, aber immerhin.
      Hab auch noch ne weitere Schwierigkeit entdeckt. Es gibt auch neuername12 (also ohne /Zahl) als value 2. Ohjee.

      gruss
      Karle

      1. 你好 Karle,

        Danke für den Post ... ich muss da erstmal versuchen durchzublicken was du da machst - aber bin dran, zwar langsam, aber immerhin.

        Wenn du Fragen hast – schiess los.

        Hab auch noch ne weitere Schwierigkeit entdeckt. Es gibt auch neuername12 (also ohne /Zahl) als value 2. Ohjee.

        In dem Fall spucht der Algorithmus zwar ein paar Warnungen wegen uninitialisierter Werte aus, aber nimmt 0 an für /Zahl. Du müsstest halt $digitpart2_a und $digitpart2_b prüfen und ggfls. mit 0 belegen, um die Warnungen abzuschalten.

        再见,
         克里斯蒂安

        --
        http://wwwtech.de/
        IRC-Clients und Irssi-Scripting | Flyspray
        Ihr wisst nicht, wie man den Menschen dient. Wie sollt ihr wissen, wie man den Goettern dienen soll?
  2. Hi,

    ich hab hier einen fiesen sort vor mir und bekomme es nicht hin.
    Ausgangslage ist ein ein HoA.

    <key>: value1 value2 ...

    a: name1 neuername1/12
    b: name1 neuername2/23
    c: name1 neuername1/1
    d: name10 neuername1/1
    e: name2 neuername1/3

      
    Hast Du die Möglichkeit, in das Array noch eine Nummer einzutragen, welche die Reihenfolge bestimmt?  
      
    Hotte
    
    -- 
    Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
    
    1. Hi,
      »»
      »» ich hab hier einen fiesen sort vor mir und bekomme es nicht hin.
      »» Ausgangslage ist ein ein HoA.
      »»
      »» ~~~perl

      <key>: value1 value2 ...

      »» a: name1 neuername1/12
      »» b: name1 neuername2/23
      »» c: name1 neuername1/1
      »» d: name10 neuername1/1
      »» e: name2 neuername1/3

      
      >   
      > Hast Du die Möglichkeit, in das Array noch eine Nummer einzutragen, welche die Reihenfolge bestimmt?  
      >   
      > Hotte  
        
      Klar, könnte ich machen -> aber vorher müsste ich diese ermitteln und stehe dann wiede vor dem selben Problem :)  
        
      Karle
      
  3. Moin Moin!

    Zum Thema "natural sort" gibt's bei http://perlmonks.org/ diverse Threads, bei CPAN einige Module (Sort::Naturally, Sort::Key::Natural, Data::Sorting).

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
    1. Moin Moin!

      Zum Thema "natural sort" gibt's bei http://perlmonks.org/ diverse Threads, bei CPAN einige Module (Sort::Naturally, Sort::Key::Natural, Data::Sorting).

      Alexander

      Also ich hab die Beispiele gesehen mit Arrays, aber wie mache ich das mit meinem HoA?

      So sortiere ich mit dem normalen sort derzeit
      foreach my $key ( sort { $ref_hoa_data->{$b}->[0] cmp $ref_hoa_data->{$a}->[0] } keys %$ref_hoa_data )

      Nun bekomme ich die Syntax nicht hin für z.B. den nsort des moduls sort::naturally, der ja mein Problem lösen sollte (zumindest mal für das erste Feld.

      Gruss
      Karle