我坚持编写转换2d数组的Perl代码。
数据位于数组“数据”中,按日期排序,然后按键排序。
我的情况应该从下表中可以理解。将选择第二列中的唯一值,然后将其分为列标题(绿表)
它应该与列数或日期/键一起使用。
之前的结构
之后的结构
我的代码:
#creates filtered array of all the unique dates and its count
my @date = @{ $data->[0] };
my @filtDate = uniq @date;
my $countFiltDate = scalar @filtDate;
#unique list of keys
my @klic = @{ $data->[1] };
my @filtKlic = uniq @klic;
#orders filtered keys
@filtKlic = sort @filtKlic;
my $countFiltKlic = scalar @filtKlic;
#count of columns
my $columnsCount = scalar @{$data};
#test code - counts how many new number columns to make.
my $columnsCountAfter = ( $columnsCount - 2 ) * $countFiltKlic;
#inserst filtered dates into first column
my $dataGraph;
for ( my $i = 0; $i < $countFiltDate; $i++ ) {
$dataGraph->[0]->[$i] = @filtDate[$i];
}
#biggest loop with number of dates
for ( my $k = 0; $k < $countFiltDate; $k++ ) {
my $l;
my $c;
#columns sount k $i
for ( my $i = 0; $i < $columnsCount - 2; $i++ ) {
#loop for different keys k $j
for ( my $j = 0; $j < $countFiltKlic; $j++ ) {
$l++; #riadok v prvej tabulke
#EVERYTHING after this part is written horibly.
# I'm trying to make it work even
#if key values are missing.
for ( my $m = 0; $m < 5; $m++ ) {
if ( $data->[1]->[ $l - 1 ] eq $filtKlic[$j] ) {
print " [" . $data->[1]->[ ( $l - 1 ) ] . ',' . $filtKlic[$j] . "]";
$dataGraph->[ $l + $c ]->[$k] = $data->[ $i + 2 ]->[ ( ( $k * $countFiltKlic ) + $j ) ];
#print " [".$data->[1]->[$j].','.($filtKlic[($j)])."]-";
print " [" . ( $i + 2 ) . ',' . ( ( $k * $countFiltKlic ) + $j ) . "]-";
print " [" . ( $l + $c ) . ',' . $k . "]<br>";
$m = 5; #just random number... i don't want to get infinite loops during testing
} else {
if ( $m = 5 ) {
$l--;
$c++;
}
$j++;
}
}
}
}
}
my @nameStlpceKlic;
@nameStlpceKlic[0] = "date";
my $o;
for ( my $i = 0; $i < $columnsCount - 2; $i++ ) {
foreach (@filtKlic) {
my $o;
$o++;
@nameStlpceKlic[$o] = @filtKlic[ ( $o - 1 ) ] . $i;
}
}
我有两个问题。
答案 0 :(得分:1)
以下是我解决此类问题的一般方法。
在第二个表格中,您按日期对数据进行分组,然后显示number1的值和number2的值。这应该为您提供有关如何组织数据结构以及打印索引所需的提示。
您当前的数据(我假设)存储在一个数组数组中。我懒得复制价值观,所以我用自己的价值制作了自己的AoA。我已经在代码中添加了评论,因此您可以看到我是如何处理此问题的。
my $arr = [
['date','key','number1','number2'],
['22.12.2013','1a','1a1-34567','1a2-1234567'],
['22.12.2013','2b','2b1-3249871','2b2-4597134'],
['22.12.2013','3c','3c1-1234567',''],
['22.12.2013','4d','4c1-3249871','4c2-4597134'],
['22.13.2013','1a','1a1-34567','1a2-1234567'],
['22.13.2013','2b','','2b2-4597134'],
['22.13.2013','3c','3c1-1234567','3c2-1234567'],
['22.13.2013','4d','4c1-3249871','4c2-4597134'],
];
# first, remove the first row, which contains the column headers.
my $col_h = shift @$arr;
my $data;
my $key_list;
foreach (@$arr) {
my %hash;
# use a hash slice with the column header array as keys
# and the array as the values
@hash{@$col_h} = @$_;
# store this hash in a data hash indexed by date then key
$data->{ $hash{date} }{ $hash{key} } = \%hash;
# compile a separate hash with the keys in it
$key_list->{ $hash{key} }++;
}
# make a sorted list of keys, ready for printing
my @key_list = sort keys %$key_list;
# remove the first two elements from the column headers ('date' and 'key')
splice(@$col_h, 0, 2);
# print out the header row for the table (I'm doing a simple tab-delim'd table)
print STDERR "Date\t";
# for each NUMBER from NUMBER1 ... NUMBERn
foreach my $c (@$col_h) {
# print "keyID NUMBERn"
map { print STDERR "$_ $c\t" } @key_list;
}
print STDERR "\n";
# Now print out the data itself. Sort by date...
foreach my $date (sort keys %$data) {
print STDERR "$date\t";
# for each NUMBER1 ... NUMBERn
foreach my $header (@$col_h) {
foreach my $key (@key_list) {
## print out the value OR - if there is no value
print STDERR ( $data->{$date}{$key}{$header} || "-" ) . "\t";
}
}
print STDERR "\n"; # end of the table row
}
输出(展开选项卡以显示):
Date 1a number1 2b number1 3c number1 4d number1 1a number2 2b number2 3c number2 4d number2
22.12.2013 1a1-34567 2b1-3249871 3c1-1234567 4c1-3249871 1a2-1234567 2b2-4597134 - 4c2-4597134
22.13.2013 1a1-34567 - 3c1-1234567 4c1-3249871 1a2-1234567 2b2-4597134 3c2-1234567 4c2-4597134
答案 1 :(得分:0)
我能够使用来自&#34;我惊恐的外星人&#34; 。 首先,不同的是我的数据以转置方式格式化为数组数组。
$arr1 = [ '2013-12-22', '2013-12-22' ];
$arr2 = [ 'Number1','Number2'];
$arr3 = [ '2328942', '679204'];
$arr4 = [ '1450398', '436713'];
同样转换的数据应保存在数组中。我写了这段代码。 (它远非完美,如果有任何建议如何进一步提高它我会很高兴听到这些。)
####################
#transpose data
my $datas = $args{DATA};
my $headers = $args{HEADERS};
my @rows = ();
my @transposed = ();
for my $row (@$datas) {
for my $column (0 .. $#{$row}) {
push(@{$transposed[$column]}, $row->[$column]);
}
}
#################################
my @arr = @transposed;
# first, define headers.
my $col_h = $args{HEADERS};
my $data;
my $key_list;
foreach (@arr) {
my %hash;
# use a hash slice with the column header array as keys
# and the array as the values
@hash{@$col_h} = @$_;
# store this hash in a data hash indexed by date then key
$data->{ $hash{date} }{ $hash{key} } = \%hash;
# compile a separate hash with the keys in it
$key_list->{ $hash{key} }++;
}
# make a sorted list of keys, ready for printing
my @key_list = sort keys %$key_list;
# remove the first two elements from the column headers ('date' and 'key')
splice(@$col_h, 0, 2);
my @output;
my @header;
# print out the header row for the table (I'm doing a simple tab-delim'd table)
#print STDERR "Date\t";
push(@header, "Date\t");
# for each NUMBER from NUMBER1 ... NUMBERn
foreach my $c (@$col_h) {
# print "keyID NUMBERn"
map { push (@header,"$_ $c\t" )} @key_list;
#map { print STDERR "$_ $c\t" } @key_list;
}
#print STDERR "<br>";
push (@output,\@header );
my $row;
my $column;
# Now print out the data itself. Sort by date...
foreach my $date (sort keys %$data) {
#print STDERR "$date\t";
$row++;
my @line;
push(@line, "$date");
# for each NUMBER1 ... NUMBERn
foreach my $header (@$col_h) {
foreach my $key (@key_list) {
## print out the value OR - if there is no value
$column++;
push (@line,( $data->{$date}{$key}{$header} || "-" ) . "\t");
#print STDERR ( $data->{$date}{$key}{$header} || "-" ) . "\t";
}
}
print STDERR "<br>"; # end of the table row
$column = 0;
push (@output,\@line );
}
my $x = 1;
return @output;
}
此代码有效,但有点难看。如果有更干净/更好的方法,请告诉我。