Perl数组或哈希变量空值处理


在perl脚本编写过程中,需要判断数组或哈希的键值或其本身是否定义存在或为空。现将这些经验总结如下:
判断hash变量是否为空的可用方法:
if (!keys %hash) { print "Empty" }
if (!%hash) { print "Empty" }
if (%my_hash) { ... do stuff ... }
if (!%hash) { print "Empty";}
a hash in scalar context returns (somewhat uselessly -- except for now,) the number of slots filled out of the number of slots allocated. so scalar %hash will equal 0 if no slots are allocated.
在标量上下文返回哈希(有些无用但现在除外),健值数量分配。所以标量%hash将等于0如果没有分配健值。
From perldoc perldata:
If you evaluate a hash in scalar context, it returns false if the hash is empty. If there are any key/value pairs, it returns true; more precisely, the value returned is a string consisting of the number of used buckets and the number of allocated buckets, separated by a slash.
如果你在标量上下文下评估一个散列,如果散列是空的它将返回false。如果有任何键/值对,它返回true;更确切地说,返回的值是一个字符串组成以及分配的数量,由一个斜杠分开。
print 'empty' unless scalar %hash;
检查hash中是否包含了空的key
$VAR1 = {
'' => 0,
'example' => 17953878,
'test' => 14504908,
'freeoa' => 14977444
};
for (keys %hash) {
length or next; # key is empty string, skip it
# $_ eq "" and next; # explicit comparison to ""
print "$_ : $hash{$_}";
}
在循环外可使用'exists'函数来检测或处理:
print "hash has empty string key\n" if exists($hash{""});
delete $hash{''};
将array或hash中的key或value置为空
my $x = 42;
$x = undef;
print defined $x ? 'DEFINED' : 'NOT';
my $x = 42;
undef $x;
print defined $x ? 'DEFINED' : 'NOT';
这两种模式将打印“NOT”。'$x = undef'和'undef $x'是一样的。它们也一样'$x = undef()'和'undef($ x)',以防你喜欢括号。
对数组元素进行undef(undef on array elements)
my @names = qw(Foo Bar Baz);
$names[1] = undef;
print Dumper \@names;
结果如下:
$VAR1 = [
'Foo',
undef,
'Baz'
];
删除数组(delete on arrays)
delete 某一数组元素这种操作方法在未来版本的perl中会移除,将使用splice方法来代替之。如要删除每三个元素,可以用此方法:splice(@names, 2, 1)
对数组进行undef(undef on arrays)
use Data::Dumper qw(Dumper);
my @names = qw(Foo Bar Baz);
undef @names;
print Dumper \@names;
$VAR1 = [];
这样数组便成为空值了。
使用'@names = ()'来代替'undef @names',结果是一样的:一个空数组。
注意,如果使用'@names = undef',将一个元素的数组undef:
$VAR1 = [
undef
];
对哈希的元素undef(undef on hash elements)
将哈希某一元素的值设为undef。
The script uses $h{Foo} = undef; to set the value of a hash key to be undef.
use Data::Dumper qw(Dumper);
my %h = (Foo => 123, Bar => 456);
$h{Foo} = undef;
print Dumper \%h;
将 %hash 的元素 'Foo' 设置为 undef:
$VAR1 = {
'Bar' => 456,
'Foo' => undef
};
undef $h{Foo}; #这样也会完全一样。
删除哈希元素(delete a hash element)
Writing delete $h{Foo}; instead of the call to undef will remove both the key and the value from the hash:
使用'delete $h{Foo}'方法,将其key及value都清除:
$VAR1 = {
'Bar' => 456
};
$h{Foo} delete; is a syntax error.
将整个hash undef(undef on a whole hash)
See this undef %h; in the following code:
use strict;
use warnings;
use Data::Dumper qw(Dumper);
my %h = (Foo => 123, Bar => 456);
undef %h;
print Dumper \%h;
$VAR1 = {};
用'%h = ()'取代'undef %h'同样将整个hash变量置空。
注意:'%h = undef;'这种写法是错误的,It will generate the following output:
Odd number of elements in hash assignment at files/eg.pl line 7.
Use of uninitialized value in list assignment at files/eg.pl line 7.
$VAR1 = {
'' => undef
};
It looks a bit odd. What happened here is that the undef we typed in was converted to an empty string generating the Use of uninitialized value in list assignment at ... warning. This became the key in the hash.
Then there was no corresponding value. This generated the Odd number of elements in hash assignment warning, and an undef was assigned to be the value of the empty-string key.
In any case, this is NOT what you want!
As a conclusion let me try to answer to straight forward question:
How do reset an array and a hash in Perl(如何重置数组、哈希)?
@a = ();
%h = ();
How do reset a complete hash or a hash key/value pair?
Reset complete hash:
%h = ();
Remove a key/value pair:
delete $h{Foo};
Remove only the value of a key/value pair:
$h{Foo} = undef;
perl howto clear a hash or array
%hash = (); # Most efficient method.
map { delete $hash{$_} } keys %hash;
delete @hash{(keys %hash)}; # Hash slice
while(my($k, $v) = each %hash ) {
delete $hash{$k};
}
for (keys %hash) {delete $hash{$_};};
delete $hash{$_} for keys %hash;
除开undef外,直接为变量赋空值亦可达到置空的目的。
@foo = (); %bar = ();
say for splice(@array);
下面的操作是错误的:
@array = undef;
先会把@array清空,再将undef做为值给@array!但对$array_ref直接赋undef却是可以的:将其内容值置空。
undef array_ref == array_ref=undef == array_ref=() == array_ref={}
undef @array; #@array undefined
$array[2] = undef; #pick element number to undefine, EQ: undef $array[2]
undef $scalar; #$scalar will be undefined
$scalar = undef; #$scalar will exist, but with no value
would assign undefined values to the datatypes. The biggest use for this would be assigning $variables to some array elements.. ie:
($value1,undef,undef,$value2,$value3,undef) = @array;
对$hash{'some'}或$hashref->{'some'}进行undef操作只会将其值(value)置为undef,并不能将该键移除(还是的使用其提供的delete方法)
undef $hash{'some'} == $hash{'some'}=undef
而对%hash而言
undef %hash == %hash=() != %hash=undef != %hash={}
%hash=undef 与 %hash={} 会导致不可预知的行为,是错误的操作!
对于hash_ref而言
undef hash_ref == hash_ref=undef == hash_ref=() != hash_ref={}
hash_ref={}会直接构建成一个空的Hash引用,前面三个直接就是undef。
参考文章
对Perl中defined、undef、exist的理解
Perl中对空值的判断处理
判断hash变量是否为空的可用方法:
if (!keys %hash) { print "Empty" }
if (!%hash) { print "Empty" }
if (%my_hash) { ... do stuff ... }
if (!%hash) { print "Empty";}
a hash in scalar context returns (somewhat uselessly -- except for now,) the number of slots filled out of the number of slots allocated. so scalar %hash will equal 0 if no slots are allocated.
在标量上下文返回哈希(有些无用但现在除外),健值数量分配。所以标量%hash将等于0如果没有分配健值。
From perldoc perldata:
If you evaluate a hash in scalar context, it returns false if the hash is empty. If there are any key/value pairs, it returns true; more precisely, the value returned is a string consisting of the number of used buckets and the number of allocated buckets, separated by a slash.
如果你在标量上下文下评估一个散列,如果散列是空的它将返回false。如果有任何键/值对,它返回true;更确切地说,返回的值是一个字符串组成以及分配的数量,由一个斜杠分开。
print 'empty' unless scalar %hash;
检查hash中是否包含了空的key
$VAR1 = {
'' => 0,
'example' => 17953878,
'test' => 14504908,
'freeoa' => 14977444
};
for (keys %hash) {
length or next; # key is empty string, skip it
# $_ eq "" and next; # explicit comparison to ""
print "$_ : $hash{$_}";
}
在循环外可使用'exists'函数来检测或处理:
print "hash has empty string key\n" if exists($hash{""});
delete $hash{''};
将array或hash中的key或value置为空
my $x = 42;
$x = undef;
print defined $x ? 'DEFINED' : 'NOT';
my $x = 42;
undef $x;
print defined $x ? 'DEFINED' : 'NOT';
这两种模式将打印“NOT”。'$x = undef'和'undef $x'是一样的。它们也一样'$x = undef()'和'undef($ x)',以防你喜欢括号。
对数组元素进行undef(undef on array elements)
my @names = qw(Foo Bar Baz);
$names[1] = undef;
print Dumper \@names;
结果如下:
$VAR1 = [
'Foo',
undef,
'Baz'
];
删除数组(delete on arrays)
delete 某一数组元素这种操作方法在未来版本的perl中会移除,将使用splice方法来代替之。如要删除每三个元素,可以用此方法:splice(@names, 2, 1)
对数组进行undef(undef on arrays)
use Data::Dumper qw(Dumper);
my @names = qw(Foo Bar Baz);
undef @names;
print Dumper \@names;
$VAR1 = [];
这样数组便成为空值了。
使用'@names = ()'来代替'undef @names',结果是一样的:一个空数组。
注意,如果使用'@names = undef',将一个元素的数组undef:
$VAR1 = [
undef
];
对哈希的元素undef(undef on hash elements)
将哈希某一元素的值设为undef。
The script uses $h{Foo} = undef; to set the value of a hash key to be undef.
use Data::Dumper qw(Dumper);
my %h = (Foo => 123, Bar => 456);
$h{Foo} = undef;
print Dumper \%h;
将 %hash 的元素 'Foo' 设置为 undef:
$VAR1 = {
'Bar' => 456,
'Foo' => undef
};
undef $h{Foo}; #这样也会完全一样。
删除哈希元素(delete a hash element)
Writing delete $h{Foo}; instead of the call to undef will remove both the key and the value from the hash:
使用'delete $h{Foo}'方法,将其key及value都清除:
$VAR1 = {
'Bar' => 456
};
$h{Foo} delete; is a syntax error.
将整个hash undef(undef on a whole hash)
See this undef %h; in the following code:
use strict;
use warnings;
use Data::Dumper qw(Dumper);
my %h = (Foo => 123, Bar => 456);
undef %h;
print Dumper \%h;
$VAR1 = {};
用'%h = ()'取代'undef %h'同样将整个hash变量置空。
注意:'%h = undef;'这种写法是错误的,It will generate the following output:
Odd number of elements in hash assignment at files/eg.pl line 7.
Use of uninitialized value in list assignment at files/eg.pl line 7.
$VAR1 = {
'' => undef
};
It looks a bit odd. What happened here is that the undef we typed in was converted to an empty string generating the Use of uninitialized value in list assignment at ... warning. This became the key in the hash.
Then there was no corresponding value. This generated the Odd number of elements in hash assignment warning, and an undef was assigned to be the value of the empty-string key.
In any case, this is NOT what you want!
As a conclusion let me try to answer to straight forward question:
How do reset an array and a hash in Perl(如何重置数组、哈希)?
@a = ();
%h = ();
How do reset a complete hash or a hash key/value pair?
Reset complete hash:
%h = ();
Remove a key/value pair:
delete $h{Foo};
Remove only the value of a key/value pair:
$h{Foo} = undef;
perl howto clear a hash or array
%hash = (); # Most efficient method.
map { delete $hash{$_} } keys %hash;
delete @hash{(keys %hash)}; # Hash slice
while(my($k, $v) = each %hash ) {
delete $hash{$k};
}
for (keys %hash) {delete $hash{$_};};
delete $hash{$_} for keys %hash;
除开undef外,直接为变量赋空值亦可达到置空的目的。
@foo = (); %bar = ();
say for splice(@array);
下面的操作是错误的:
@array = undef;
先会把@array清空,再将undef做为值给@array!但对$array_ref直接赋undef却是可以的:将其内容值置空。
undef array_ref == array_ref=undef == array_ref=() == array_ref={}
undef @array; #@array undefined
$array[2] = undef; #pick element number to undefine, EQ: undef $array[2]
undef $scalar; #$scalar will be undefined
$scalar = undef; #$scalar will exist, but with no value
would assign undefined values to the datatypes. The biggest use for this would be assigning $variables to some array elements.. ie:
($value1,undef,undef,$value2,$value3,undef) = @array;
对$hash{'some'}或$hashref->{'some'}进行undef操作只会将其值(value)置为undef,并不能将该键移除(还是的使用其提供的delete方法)
undef $hash{'some'} == $hash{'some'}=undef
而对%hash而言
undef %hash == %hash=() != %hash=undef != %hash={}
%hash=undef 与 %hash={} 会导致不可预知的行为,是错误的操作!
对于hash_ref而言
undef hash_ref == hash_ref=undef == hash_ref=() != hash_ref={}
hash_ref={}会直接构建成一个空的Hash引用,前面三个直接就是undef。
参考文章
对Perl中defined、undef、exist的理解
Perl中对空值的判断处理