无法在 Perl 循环中访问哈希查找表

Posted

技术标签:

【中文标题】无法在 Perl 循环中访问哈希查找表【英文标题】:Cannot Access Hash Lookup Table In Perl Loop 【发布时间】:2011-05-17 18:44:19 【问题描述】:

我正在编写一个比较两个 excel 文件数据的 Perl 脚本。

我目前正在获取其中一个 excel 文件的两列并将其存储在哈希中。我用于密钥的数据是电子邮件地址,该值只是 excel 表中的另一个值(不重要)。我只是想将所有电子邮件存储为哈希键,以便我可以遍历另一个(“删除”)excel 文件,并查看电子邮件是否存在于原始成员表中。

我的意图大致如下:

1) 创建哈希和查找数组:

my %members_list;
foreach my $row (2..$MembersLastRow)
    $members_listlc($Members->Cells($row,1)->'Value') = lc($Members->Cells($row,2)->'Value'); 


my @removals_list;
foreach my $row (2..$RemovalsLastRow)

    push(@removals_list, lc($Removals->Cells($row,1)->'Value'));

2)遍历查找数组,检查hash中是否存在:

foreach my $key (sort @removals_list)

    print $key;
    if($members_list$key)
        print " - MATCH!";
    
    print "\n";

问题是当我尝试运行它时,从来没有任何匹配。删除列表中的所有元素都应存储在 members_list 哈希中。我尝试将 $members_list$key 打印到屏幕上,然后它会出现“未初始化使用”等等。

我已经为此奋斗了好几天,非常感谢任何帮助。

这是我正在使用的整个代码页面!!!

use strict;
use 5.010;
use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';

$Win32::OLE::Warn = 3;                                # die on errors...

# get already active Excel application or open new
my $Excel = Win32::OLE->GetActiveObject('Excel.Application')
    || Win32::OLE->new('Excel.Application', 'Quit');  
$Excel->DisplayAlerts=0;   
# open Excel file

my $Book = $Excel->Workbooks->Open("**FILENAME1**"); 
my $Book2 = $Excel->Workbooks->Open("**FILENAME2**"); 

# You can dynamically obtain the number of worksheets, rows, and columns
# through the Excel OLE interface.  Excel's Visual Basic Editor has more
# information on the Excel OLE interface.  Here we just use the first
# worksheet, rows 1 through 4 and columns 1 through 3.


my $Members = $Book->Worksheets(1);
$Members->Name = "Members - Points";
my $Results = $Book->Worksheets(2);
$Results->Name = "Perl Results -Saved";

my $Removals = $Book2->Worksheets(1);
$Removals->Name = "Removals";

my $count=0;
my %members_list;
my @removals_list;

my $MembersLastRow = &findLastRow($Members);
print "After Members Last Row\n";
my $RemovalsLastRow = &findLastRow($Removals);
print "After Removals Last Row\n";

foreach my $row (2..$MembersLastRow)

    next unless defined $Members->Cells($row,1)->'Value';
    $members_listlc($Members->Cells($row,1)->'Value') = lc($Members->Cells($row,2)->'Value'); 

foreach my $row (2..$RemovalsLastRow)

next unless defined $Removals->Cells($row,1)->'Value';
push(@removals_list, lc($Removals->Cells($row,1)->'Value'));


#DO THE VLOOKUP
my $matches=1;
print "Now doing comparisons......\n";
$Results->Cells($matches,1)->'Value' = "Removal List";
$Results->Cells($matches,2)->'Value' = "Corresponding Member List";


foreach my $key (sort @removals_list)

    print $key;
    if($members_list$key)
        print " - MATCH!";
    
    print "\n";


print "\nComparisons Complete.\n";

sub findLastRow

    $_[0]->UsedRange->Find(What=>"*",
    SearchDirection=>xlPrevious,
    SearchOrder=>xlByRows)->Row;


sub findLastCol

    $_[0]->UsedRange->Find(What=>"*", 
    SearchDirection=>xlPrevious,
    SearchOrder=>xlByColumns)->Column;


$Book->Save();

【问题讨论】:

使用Data::Dumper 这是一个标准的 Perl 模块,并让它转储出成员列表和删除列表的内容。这会告诉你为什么你可能没有得到任何匹配。 【参考方案1】:

如果您存储的值可能是 undef,您希望这样做:

if ( exists $members_list$key ) 

您确定您访问的是相同的 %members_list 哈希吗?它没有超出范围或被后来的my %members_list 取代?

这说明了什么:

use Data::Dumper;
$Data::Dumper::Terse = $Data::Dumper::Useqq = 1;
print Data::Dumper::Dumper(  'removals' => [ sort @removals_list ], 'members' => [ sort keys %members_list ]  );

?

【讨论】:

我刚试过,但它做同样的事情。我看不出它是如何超出范围的。在初始列表之后,我没有“我的 %members_list”。这真的很烦人,因为我觉得这应该有效。我会提到我正在使用的模块:use strict;使用 5.010;使用 Win32::OLE qw(in with);使用 Win32::OLE::Const 'Microsoft Excel'; @bOkeifus:在我的回答中添加了一个问题 没关系,我发现了问题。问题根本不在于代码。问题是该程序应该检查原始文件以获取删除列表,然后将其删除。我正在一个列表中测试该程序,该列表已经缺少删除。因此,当它没有找到任何东西时,这就是我认为代码被破坏的原因。实际上是我使用的样本导致了这个问题。我真的很感谢你和我一起研究这个,我认为这一切看起来也很好,显然我们都是对的!

以上是关于无法在 Perl 循环中访问哈希查找表的主要内容,如果未能解决你的问题,请参考以下文章

查找:哈希表

在哈希表或排序列表中查找项目哪个更快?

在哈希表中查找冲突

数据结构查找---散列表(哈希表)查找

数据结构:哈希表(根据数值查找的key-value容器)

大白话之哈希表和哈希算法