Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果在Perl中键相同,则将值追加到哈希_Perl_Hash - Fatal编程技术网

如果在Perl中键相同,则将值追加到哈希

如果在Perl中键相同,则将值追加到哈希,perl,hash,Perl,Hash,问题是读取每一行都有值的文件。文件的内容看起来像 3ssdwyeim3,3ssdwyeim92017-03-16,09:10:35.372,0.476,EndInbound 第三天,第三天,2017-03-16,09:10:35.369,0.421,内出 3ssdwyfxc0,3ssdwyfxfi,2017-03-16,09:10:35.456,0.509 3ssdwyfxc0,3ssdwyhg0v,2017-03-16,09:10:35.453,0.436,内出 第一个逗号前的字符串是键,最

问题是读取每一行都有值的文件。文件的内容看起来像

3ssdwyeim3,3ssdwyeim92017-03-16,09:10:35.372,0.476,EndInbound
第三天,第三天,2017-03-16,09:10:35.369,0.421,内出
3ssdwyfxc0,3ssdwyfxfi,2017-03-16,09:10:35.456,0.509
3ssdwyfxc0,3ssdwyhg0v,2017-03-16,09:10:35.453,0.436,内出
第一个逗号前的字符串是键,最后一个和最后第二个逗号之间的字符串是值

i、 e.对于第一行,3ssdwyeim3成为键,0.476值

现在,当我们在每一行上循环时,如果键存在,我们必须连接由逗号分隔的值

因此,对于下一个新行,由于键已存在,键仍保留
3ssdwyeim3
,但值更新为
0.476,0.421。

最后,我们必须打印文件中的键和值

我已经写了一个代码来实现同样的功能,如下所示

sub-findbreakdown{
我的($out)=@;
我的%timeLogger;
打开读取,“out.txt”或“die”无法打开.txt进行读取:$!”;
OpenOutBD,“>$out\\u breakdown.csv”或die“无法打开$out\\u breakdown.csv进行写入:$!”;
而(){
如果(/(.*)、.*、.*、(.*)、.*/){
$btxnId=$1;
$time=$2;
if(!$timeLogger{$btxnId}){
$timeLogger{$btxnId}=$time;
}
否则{
$previousValue=$timeLogger{$btxnId};
$newValue=join“,”,$previousValue,$time;
$timeLogger{$btxnId}=$newValue;
}
}
foreach(排序键%timeLogger){
打印输出BD“$\$timeLogger{$\}\n”;
}
}
闭关自守;
仔细阅读;
}
然而,有些地方出了问题,它的印刷方式是这样的

3ssdwyeim3,0.476
3ssdwyeim3,0.476,0.421
3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509
3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509,0.436
3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509,0.436
鉴于预期为:

3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509,0.436

您的程序运行正常,但在处理每一行后,您正在打印整个哈希的当前状态。

因此,在散列键具有完整的值集之前打印它们,并且有许多重复的行

如果将打印到程序末尾的
foreach
循环移动(或者简单地使用调试器检查变量),您将发现哈希的最终状态正是您所期望的


编辑:我之前认为问题出在下面,但这是因为我误读了您问题中的样本数据

此正则表达式不理想:

if (/(.*),.*,.*,.*,(.*),.*/) {
*
是贪婪的,将尽可能多地匹配(包括一些带有逗号的内容)。因此,如果任何一行包含六个以上逗号分隔的项,那么第一个匹配组中将包含多个项。在实际数据中,这可能不是问题,但这不是编写代码的理想方式。这个表达式的含混不清

最好这样写:

if (/^([^,]*),[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$/) {
这将只匹配正好有六个项目的行


或考虑在输入行上使用拆分,这将是一个更干净的解决方案。

<强>您的程序运行正常,但在处理每一行之后,您正在打印整个哈希的当前状态。>/P> 因此,在散列键具有完整的值集之前打印它们,并且有许多重复的行

如果将打印到程序末尾的
foreach
循环移动(或者简单地使用调试器检查变量),您将发现哈希的最终状态正是您所期望的


编辑:我之前认为问题出在下面,但这是因为我误读了您问题中的样本数据

此正则表达式不理想:

if (/(.*),.*,.*,.*,(.*),.*/) {
*
是贪婪的,将尽可能多地匹配(包括一些带有逗号的内容)。因此,如果任何一行包含六个以上逗号分隔的项,那么第一个匹配组中将包含多个项。在实际数据中,这可能不是问题,但这不是编写代码的理想方式。这个表达式的含混不清

最好这样写:

if (/^([^,]*),[^,]*,[^,]*,[^,]*,([^,]*),[^,]*$/) {
这将只匹配正好有六个项目的行


或考虑在输入行上使用拆分,这将是一个更干净的解决方案。

< P>这比你所做的要简单得多。您只需将每一行拆分为字段,然后使用
push
将值添加到与键对应的列表中

我相信您可以将其修改为从外部文件读取,而不是从
数据
文件句柄读取

使用严格;
使用“全部”警告;
我的%数据;
而(){
我的@fields=split/,/;
推送{$data{$fields[0]},$fields[-2];
}
对于我的$key(对key%数据进行排序){
打印联接(“,”,$key,@{$data{$key}),“\n”;
}
__资料__
3ssdwyeim3,3ssdwyeim92017-03-16,09:10:35.372,0.476,EndInbound
第三天,第三天,2017-03-16,09:10:35.369,0.421,内出
3ssdwyfxc0,3ssdwyfxfi,2017-03-16,09:10:35.456,0.509
3ssdwyfxc0,3ssdwyhg0v,2017-03-16,09:10:35.453,0.436,内出
输出
3ssdwyeim3,0.476,0.421
3ssdwyfxc0,0.509,0.436

这比您所做的要简单得多。您只需将每一行拆分为字段,然后使用
push
将值添加到与键对应的列表中

我相信您可以将其修改为从外部文件读取,而不是从
数据
文件句柄读取

使用严格;
使用“全部”警告;
我的%数据;
而(){
我的@fields=split/,/;
推送{$data{$fields[0]},$fields[-2];
}
对于我的$key(对key%数据进行排序){
打印联接(“,”,$key,@{$data{$key}),