Jas*_*ssi 2 perl hash exists map
如果密钥存在于%hash中,我试图将键值对放在%hash1上.数组中有一个元素,%hash ex上没有条目:@array =(1,2,3,4,5); #there在%hash处没有密钥1的哈希条目
所以我认为map会完成这项工作,我会在我的新哈希中获得4个键,即%hash1,但它会提供5个键.与此同时,我尝试了foreach并且它起作用了.我妄想我们可以用地图取代foreach,但这个案例让我思考.谁能解释一下,我的逻辑出错了?
#Method 1. Comment it while using Method 2
%hash1 = map { $_=>$hash{$_} if(exists $hash{$_}) } @array;
# Method 2. Comment whole loop while using method 1
foreach (@array){
$hash1{$_} = $hash{$_} if(exists $hash{$_});
}
Run Code Online (Sandbox Code Playgroud)
你的问题是你的map表达式为第一个元素返回一个false值undef@array.并且它被字符串化为空字符串,因为它被用作散列键. (在评论中,Borodin指出这种解释是不正确的.事实上,空字符串来自于exists键为"1"时返回的false值)
如果你一)打开你可能会得到一个什么样正在做一个更好的主意strict,并warnings和b)使用Data::Dumper显示散列一旦你创建它.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Data::Dumper;
my @array = (1 .. 5);
my %hash = ( 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five' );
my %hash1 = map { $_=>$hash{$_} if(exists $hash{$_}) } @array;
say Dumper \%hash1;
Run Code Online (Sandbox Code Playgroud)
这表明你最终得到这样的哈希:
$ ./hash
Odd number of elements in hash assignment at ./hash line 12.
$VAR1 = {
'' => 2,
'three' => 4,
'five' => undef,
'two' => 3,
'four' => 5
};
Run Code Online (Sandbox Code Playgroud)
您正在生成具有奇数个元素的列表.这并没有令人愉快的哈希.
在构建哈希时,您需要确保拥有偶数个元素.因此,当您使用时,map您需要为每次迭代返回零或两个元素.所以你需要这样的东西:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
use Data::Dumper;
my @array = (1 .. 5);
my %hash = ( 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five' );
my %hash1 = map { exists $hash{$_} ? ($_ => $hash{$_}) : () } @array;
say Dumper \%hash1;
Run Code Online (Sandbox Code Playgroud)
请注意,当在第一个哈希中找不到键时,我们显式返回一个空列表.
$ ./hash2
$VAR1 = {
'4' => 'four',
'3' => 'three',
'2' => 'two',
'5' => 'five'
};
Run Code Online (Sandbox Code Playgroud)