【问题标题】:Matching elements from 2 arrays in perl匹配perl中2个数组的元素
【发布时间】:2011-11-17 23:16:15
【问题描述】:

现在我正在尝试同步按日期列出的两个数据文件,以便稍后进行比较。但是我似乎不能只打印日期匹配的行。此时,我已将每个文件的数据分成 2 个数组。我只需要找到两个数组中的日期并将它们打印出来。任何建议将不胜感激。

这是我正在使用的原始数据的示例集,每个文件的格式相同:

09/11/2009,00:56:00,51.602,47.894,87,88,0,1032 09/12/2009,00:56:00,57.794,55.796,93,54,0,1023.6 09/13/2009,00:56:00,64.292,62.204,93,66,0,1014.4 09/14/2009,00:56:00,61.592,55.4,80,25,0,1009.6 09/15/2009,00:56:00,58.604,53.798,84,31,0,1009.1 09/16/2009,00:56:00,53.6,48.902,84,45,0,1017

我已将日期拆分为每个文件的数组。我的最终目标是只打印两个文件都有数据的代码行。所以要做到这一点,我想将 2 个数组与作为日期的元素进行比较。

我的初始代码如下所示:

foreach $bdate(@bdate){
while (<PL>){
    chomp;
    @arr = split (/,/);
    $pday=$arr[1];
    push @pdate, $pday;
    if ($bdate eq $pdate){
        print "$bdate,$pday\n";
    }
}

【问题讨论】:

  • “按日期列出”是什么意思?你能提供一些示例代码来说明你已经走了多远,哪些部分没有工作?
  • 这里是我的数据集的示例,出于我的问题的目的,我已经拆分了保持 mm/dd/yyyy 格式的日期并将其推送到一个数组中。我需要获取其中两个数组并仅找到两个数组中的日期。 02/12/2010,00:56:00,27.302,15.602,61,27,3.24193043478261,1001 02/13/2010,00:56:00,26.006,6.008,42,75,1.6209652173913,1005.8/20 2010,00:56:00,26.708,16.502,65,329,18.9112608695652,992.9 02/15/2010,00:56:00,30.902,19.004,61,287,8.64514782608696,996.8
  • 这是我尝试的第一个代码示例: foreach $bdate(@bdate){ while (){ chomp; @arr = 拆分 (/,/); $pday=$arr[1];推送@pdate,$pday; if ($bdate eq $pdate){ print "$bdate,$pday\n"; } }
  • 编辑您的问题而不是添加 cmets - 它可以更轻松地格式化代码以提高可读性
  • 我刚刚在我的数据中注意到的一件事是,一个文件是 mm/dd/yy 格式,而另一个是 mm/dd/yyyy 格式。让我回去解决这个问题,然后重试您对我的第一个建议。感谢您的患者帮助我。

标签: perl


【解决方案1】:

一种(多种)方法是遍历每个数组一次,构建如下哈希;

for (@array1, @array2) {
    $dates{$_}++;
}

那么你就可以打印出2或更大的值对应的键了;

print $_,"\n" for grep {$dates{$_} > 1} keys %dates;

(未经测试,在没有 perl 的机器上编写)

...快速搜索CPAN 会出现List::Compare,在这个例子中;

$lc = List::Compare->new(\@Llist, \@Rlist);

@intersection = $lc->get_intersection;

【讨论】:

  • 感谢您的建议,但是第一种方法未能省略第二个数组中的日期而不是第一个数组中的日期。第二种方法我不能使用,因为该模块没有安装在我的数据所在的服务器上。它是一个学校服务器,所以我将无法安装它。碰巧有其他建议吗?
  • @Paul,这个答案和其他答案是在列表(交集)中查找公共元素的常用方法。出于这个原因,我怀疑您的数据或您如何解释它可能有一些有趣的地方。您能否编辑您的问题以包含示例数据和预期结果?
  • 很可能我如何解释它是问题所在,我很新并且自学perl。我在上面列出了我正在使用的原始数据示例。在我的脚本中,我只将日期放入了我正在使用的两个文件的数组中。您建议的第一种方法可以很好地消除第一个数组中不在第二个数组中的日期,但是打印了第二个数组中不存在的几个日期。我想我的预期结果是打印出两个数组共有的唯一日期列表。
  • 在我解决了我的数据问题后,您的第一个建议效果非常好,我必须对输出进行排序,使其按顺序读取,但这是一项简单的任务。当我对照手工完成的样品检查结果时,它发现了,甚至发现了几个错误。感谢所有的帮助,这应该可以帮助我完成我的工作。
  • 在这种情况下,Paul,请选择此答案作为“已接受”答案。
【解决方案2】:

这是来自perlfaq4 的示例(稍微简化了一点):

my (@intersection, %count);

for my $element (@array1, @array2) { $count{$element}++ }

for my $element (keys %count) {
    push @intersection, $element if $count{$element} > 1;        
}

更惯用的版本:

my (%union, %isect);
for my $e (@array1, @array2) { $union{$e}++ && $isect{$e}++ }

my @intersection = keys %isect;

这两种方法都假定给定数组中的每个元素都是唯一的。

【讨论】:

  • 感谢您的建议,但是第一种方法没有产生任何结果,第二种方法产生了结果但是它们是不正确的。当我手动检查输出时,它包含几个不在两个数组中的日期。感谢您的宝贵时间,您还有其他建议吗?
猜你喜欢
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
  • 2020-11-08
  • 2017-10-16
相关资源
最近更新 更多