Perl:在复杂哈希中生成数组

编程入门 行业动态 更新时间:2024-10-19 02:23:38
本文介绍了Perl:在复杂哈希中生成数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

为了使我的数据更易于访问,我想将我的表格数据存储在复杂的散列中.当脚本循环遍历我的数据时,我正在尝试增加一个HoHoHoA".根据perldsc"中的指南:

In the quest to make my data more accessible, I want to store my tabulated data in a complex hash. I am trying to grow a 'HoHoHoA' as the script loops over my data. As per the guidelines in 'perldsc':

push @ { $hash{$column[$i]}{$date}{$hour} }, $data[$i];

脚本编译和运行没有问题,但不会向散列添加任何数据:

The script compiles and runs without a problem, but doesn't not add any data to the hash:

print $hash{"Frequency Min"}{"09/07/08"}{"15"};

即使键应该存在,也不返回任何内容.在哈希上运行存在"表明它不存在.

returns nothing even though the keys should exist. Running an 'exists' on the hash shows that it does not exist.

我正在读取的数据文件如下所示:

The data file that I am reading looks like this:

DATE TIME COLUMN1 COLUMN2 COLUMN3... 09/06/2008 06:12:56 56.23 54.23 56.35... 09/06/2008 06:42:56 56.73 55.28 54.52... 09/06/2008 07:12:56 57.31 56.79 56.41... 09/06/2008 07:42:56 58.24 57.30 58.86... . . .

我想将任何给定日期和小时的数组中每一列的值组合在一起,因此 {COLUMN}、{DATE} 和 {HOUR} 的三个哈希值.

I want to group together the values of each column in an array for any given date and hour, hence the three hashes for {COLUMN}, {DATE} and {HOUR}.

最终的结构将如下所示:

The resultant structure will look like this:

%monthData = ( "COLUMN1" => { "09/06/2008" => { "06" => [56.23,56.73...], "07" => [57.31,58.24...] } }, "COLUMN2" => { "09/06/2008" => { "06" => [54.23,55.28...], "07" => [56.79,57.30...] } }, "COLUMN3" => { "09/06/2008" => { "06" => [56.35,54.52...], "07" => [56.41,58.86...] } } );

看看我的代码:

use feature 'switch'; open DATAFILE, "<", $fileName or die "Unable to open $fileName !\n"; my %monthData; while ( my $line = <DATAFILE> ) { chomp $line; SCANROWS: given ($row) { when (0) { # PROCESS HEADERS @headers = split /\t\t|\t/, $line; } default { @current = split /\t\t|\t/, $line; my $date = $current[0]; my ($hour,$min,$sec) = split /:/, $current[1]; # TIMESTAMP FORMAT: dd/mm/yyyy\t\thh:mm:ss SCANLINE: for my $i (2 .. $#headers) { push @{ $monthData{$headers[$i]}{$date}{$hour} }, $current[$i]; } } } } close DATAFILE; foreach (@{ $monthData{"Active Power N Avg"}{"09/07/08"}{"06"} }) { $sum += $_; $count++; } $avg = $sum/$count; # $sum and $count are not initialized to begin with. print $avg; # hence $avg is also not defined.

希望我的需求足够清楚.如何将值附加到这些子哈希中的数组?

Hope my need is clear enough. How can I append values to an array inside these sub-hashes?

推荐答案

这应该适合你.

#!/usr/bin/perl use strict; use warnings; use List::Util qw/sum/; sub avg { sum(@_) / @_ } my $fileName = shift; open my $fh, "<", $fileName or die "Unable to open $fileName: $!\n"; my %monthData; chomp(my @headers = split /\t+/, <$fh>); while (<$fh>) { chomp; my %rec; @rec{@headers} = split /\t+/; my ($hour) = split /:/, $rec{TIME}, 2; for my $key (grep { not /^(DATE|TIME)$/ } keys %rec) { push @{ $monthData{$key}{$rec{DATE}}{$hour} }, $rec{$key}; } } for my $column (keys %monthData) { for my $date (keys %{ $monthData{$column} }) { for my $hour (keys %{ $monthData{$column}{$date} }) { my $avg = avg @{ $monthData{$column}{$date}{$hour} }; print "average of $column for $date $hour is $avg\n"; } } }

注意事项:

  • strict 和 警告 pragmas
  • List::Util 模块获取求和函数
  • 将数组放入标量上下文中以获取数组中的项数(在 avg 函数中)
  • 更安全的三个参数版本的 open
  • 词法文件句柄(而不是旧的裸字样式文件句柄)
  • 首先在循环外读取头文件,以避免在循环内有特殊的逻辑
  • 使用 hash slice 将文件数据放入结构化记录中立>
  • 避免使用 split 的第三个参数分割不必要的时间立>
  • 通过只在列表赋值中指定我们想要捕获的变量来避免无用的变量
  • 使用 grep 防止将 DATE 和 TIME 键放入 %monthData
  • 嵌套的 for 循环每个处理哈希中的一个级别
  • strict and warnings pragmas
  • List::Util module to get the sum function
  • putting an array in scalar context to get the number of items in the array (in the avg function)
  • the safer three argument version of open
  • the lexical filehandle (rather than the old bareword style filehandle)
  • reading the headers first outside the loop to avoid having to have special logic inside it
  • using a hash slice to get the file data into a structured record
  • avoiding splitting the time more than necessary with the third argument to split
  • avoiding useless variables by only specifying the variable we want to catch in the list assignment
  • using grep to prevent the DATE and TIME keys from being put in %monthData
  • the nested for loops each dealing with a level in the hash

更多推荐

Perl:在复杂哈希中生成数组

本文发布于:2023-10-26 23:46:41,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1531694.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数组   Perl   哈希中

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!