2016-07-07 4 views
-1

Also habe ich ein Programm, das sortierte Daten (in absteigender Reihenfolge) basierend auf zwei Spalten einliest und diese Daten in eine Textdatei ausgibt, die die Daten in eine Textdatei einfügt. Das Problem, auf das ich stoße, ist, dass es keine Ausgabe in der gleichen Reihenfolge erzeugt, wie es in das Programm eingelesen wurde.wie die Reihenfolge zu beheben, in der mein Programm ausgibt?

Hier ist ein Beispiel des Datensatzes:

2, 1, 20, 1, 10, 28.5714285, 0, 
2, 1, 72, 3, 7, 20, 0, 
2, 2, 20, 3, 19, 52.7777777, 0, 
5, 1, 66, 3, 199, 21.1927582, 0, 
5, 1, 5, 2, 153, 16.2939297, 0, 

Hier ist ein Beispiel eines Ausgangs aus der Ordnung:

fci 
u 
csno=51 svgrp=0 antfc= 2 
cdmanbr_list1.ncs_c[1]= 51 
cdmanbr_list1.nghbrantf[1]= 1 
cdmanbr_list1.pilot_pn[1]= 
cdmanbr_list1.pgn_c[1]= 0 
u 
u 
csno=66 svgrp=0 antfc= 2 
cdmanbr_list1.ncs_c[1]= 66 
cdmanbr_list1.nghbrantf[1]= 1 
cdmanbr_list1.pilot_pn[1]= 
cdmanbr_list1.pgn_c[1]= 0 
u 
u 
csno=51 svgrp=0 antfc= 3 
cdmanbr_list1.ncs_c[1]= 51 
cdmanbr_list1.nghbrantf[1]= 1 
cdmanbr_list1.pilot_pn[1]= 
cdmanbr_list1.pgn_c[1]= 0 
u 

Hinweis, wie der Wert des dritten „CsNO“ (51) ist kleiner als der zweite "csno" -Wert (66). Und obwohl es zwei "csno" mit gleichem Wert gibt, sind die "antfc" -Werte unterschiedlich. Die gewünschte Ausgabe ist die folgende:

fci 
u 
csno=51 svgrp=0 antfc= 2 
cdmanbr_list1.ncs_c[1]= 51 
cdmanbr_list1.nghbrantf[1]= 1 
cdmanbr_list1.pilot_pn[1]= 
cdmanbr_list1.pgn_c[1]= 0 
u 
u 
csno=51 svgrp=0 antfc= 3 
cdmanbr_list1.ncs_c[1]= 51 
cdmanbr_list1.nghbrantf[1]= 1 
cdmanbr_list1.pilot_pn[1]= 
cdmanbr_list1.pgn_c[1]= 0 
u 
u 
csno=66 svgrp=0 antfc= 2 
cdmanbr_list1.ncs_c[1]= 66 
cdmanbr_list1.nghbrantf[1]= 1 
cdmanbr_list1.pilot_pn[1]= 
cdmanbr_list1.pgn_c[1]= 0 
u 

Hier ist eine Kopie des Programms:

#!/usr/bin/perl 
use POSIX qw(strftime); 

($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = 
    localtime(time); 

my $bdate = sprintf("%02d%02d%02d", $mon + 1, $mday - 7, $year - 100); 
my $edate = sprintf("%02d%02d%02d", $mon + 1, $mday - 1, $year - 100); 

my $newresult = "/home/user/newresults/recommended_$bdate-$edate.csv"; 
my $script = "/home/user/update_scripts/update_$bdate-$edate.txt"; 

my $h; 
my $k; 
my $n; 
my $fh = undef; 
open($fh, '<', $newresult) or die $!; 
open($fsh, '>', $script) or die $!; 
print $fsh "fci\n"; 
while (my $line = <$fh>) { 
    next if $. < 2; 
    chomp $line; 
    my @array = split(/\,/, $line); 
    my $key = "csno=$array[0] svgrp=0 antfc=$array[1]"; 
    push(@{ $h->{$key} }, $array[6]); 
    push(@{ $k->{$key} }, $array[2]); 
    push(@{ $n->{$key} }, $array[3]); 
} ## end while (my $line = <$fh>) 

foreach my $key (keys %{$h}) { 
    print $fsh "u\n"; 
    print $fsh "$key\n"; 
    if (@{ $h->{$key} } <= 12) { 
     for (my $i = 1 ; $i <= @{ $h->{$key} } ; $i++) { 
      my $m = $i - 1; 
      print $fsh "cdmanbr_list1.ncs_c[$i]=${$k->{$key}}[$m]\n"; 
      print $fsh "cdmanbr_list1.nghbrantf[$i]=${$n->{$key}}[$m]\n"; 
      print $fsh "cdmanbr_list1.pilot_pn[$i]=\n"; 
      print $fsh "cdmanbr_list1.pgn_c[$i]=${$h->{$key}}[$m]\n"; 
     } ## end for (my $i = 1 ; $i <=...) 
     for (my $i = @{ $h->{$key} } + 1 ; $i < 13 ; $i++) { 
      my $m = $i - 1; 
      print $fsh "cdmanbr_list1.ncs_c[$i]=\n"; 
      print $fsh "cdmanbr_list1.nghbrantf[$i]=\n"; 
      print $fsh "cdmanbr_list1.pilot_pn[$i]=\n"; 
      print $fsh "cdmanbr_list1.pgn_c[$i]=\n"; 
     } ## end for (my $i = @{ $h->{$key...}}) 
    } ## end if (@{ $h->{$key} } <=...) 
    print $fsh "u\n"; 
} ## end foreach my $key (keys %{$h...}) 
+2

* „und Outfiles diese Daten in eine Textdatei, die die Daten in eine Textdatei-Stecker“ * Ich habe noch nie von * outfiling * gehört, und wie funktioniert diese Textdatei, die Sie „outfile“ die Daten in Stecker eine andere Textdatei? – Borodin

+2

Bitte * immer * 'benutzen Sie strict' und' verwenden Sie Warnungen 'all'' oben in jedem Perl-Programm, das Sie schreiben, besonders bevor Sie es veröffentlichen und um Hilfe bitten. Es hat wenig Sinn, all diese "meine" Deklarationen ohne "use strict" einzugeben. – Borodin

Antwort

0

Die Ursache des Problems ist, dass in

foreach my $key (keys%{$h}){ 

Sie erwarten, dass die Tasten der Hash wird in einer vordefinierten Reihenfolge sein. So funktioniert Hashes nicht.

2 vernünftige Lösungen sind:

  • (für Aufwand optimieren) Wenn Sie die Eingabedatei wissen sortiert wird, wie Sie wünschen, $key in ein Array schieben, wie Sie es %$h und interrate über stattdessen bauen. dh

    foreach my $key (@keyorder) {

  • (für Speicher optimieren) nehmen Sie die (scheinbar) unsortierte Liste von Schlüsseln und sortieren sie:

    foreach my $key (sort { ### comparison here ### } keys %{$h}) {

Wo Ihr Vergleich die Form von könnten: ((split $a, /=/)[1] <=> (split $b, /=/)[1]) || ((split $a, /=/)[-1] <=> (split $b, /=/)[-1]) abhängig von den Details Ihrer Sortieranforderungen.

Während C-Stil für Schleifen ihren Platz in Perl haben, könnten Ihre inneren Schleifen von etwas idiomatischem Perl profitieren.

for my $i (1 .. @{$h->{key}}) { 
    #stuff 
} 
for my $i (@{$h->{key}}+1 .. 12) { 
    #other stuff 
} 
+0

Wie würde es aussehen, wenn ich die Zeichenkette '$ key' in ein Array drücke, während ich '% $ h' baue? Wie kann das gemacht werden? Ich schätze die Hilfe! –

+0

@ m.lochhead Sie machen bereits 3 kompliziertere Pushs im Build-Prozess, also habe ich mir vorgestellt, dass Sie mit 'push @keyorder $ key;' auf eigene Faust ... kommen würden. – tjd

+0

Oh ok, ich habe das nicht gemacht Ich weiß, ob es einen bestimmten Weg gäbe, an den ich mich wenden sollte oder nicht. vielen Dank! –

Verwandte Themen