所以我有一个程序可以根据两列输入排序数据(按降序递增),并将这些数据输出到一个文本文件中,该文件将数据插入文本文件中。我遇到的问题是它不会以与读入程序相同的顺序产生输出。
以下是数据集的示例:
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,
以下是无序输出的示例:
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
注意第三个“csno”(51)的值是如何小于第二个“csno”值(66)。即使有2个相同值的“csno”,“antfc”值也不同。所需的输出如下:
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
以下是该计划的副本:
#!/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...})
答案 0 :(得分:0)
问题的根源在于
foreach my $key (keys%{$h}){
您期望哈希的键将以某种预定义的顺序排列。这不是哈希的工作方式。
2个合理的解决方案是:
(针对工作量进行优化)如果您知道输入文件已根据需要进行排序,请在构建$key
时将%$h
推送到数组中,然后通过它进行交互。即。
foreach my $key (@keyorder) {
(针对内存进行优化)获取(显然)未排序的密钥列表并对其进行排序:
foreach my $key (sort { ### comparison here ### } keys %{$h}) {
您的比较可能采用以下形式:((split $a, /=/)[1] <=> (split $b, /=/)[1]) || ((split $a, /=/)[-1] <=> (split $b, /=/)[-1])
,具体取决于您的分类要求的详细信息。
虽然C样式for循环在Perl中占有一席之地,但你的内部循环可以从一些惯用的Perl中受益。
for my $i ( 1 .. @{$h->{key}} ) {
#stuff
}
for my $i ( @{$h->{key}}+1 .. 12 ) {
#other stuff
}