Perl哈希数组使用
ref of hashmerge of hashes
按哈希值的大小排序(How to sort a hash of hashes by value)
hash的一些数量的判断
Checking for existence of hash subkey but creates key automatic
-------------------------------
ref of hash
How can I create an anonymous hash from an existing hash
my $new_hash = { %existing_hash };
Note that this solution does not make a deep copy.
I think you need to be careful here. Consider the following hash:
my %hash = (1 => 'one',2 => 'two');
There are two ways you can get a reference from this:
my $ref = \%hash;
my $anon = {%hash};
$ref is a reference to the original hash and can be used similarly to %hash. $anon is a reference to an anonymous copy of the original hash; it will have the same data but changing it won't change the original hash and vice versa.
So, for example, to start with both of these statements will have the same output
print $ref->{1},"\n";
> one
print $anon->{1},"\n";
> one
But if I change the original hash:
$hash{1} = "i";
They two print statements would output different values:
print $ref->{1},"\n";
> i
print $anon->{1},"\n";
> one
-------------------------------
merge of hashes-合并Hash数组
If you mean take the union of their data, just do:
%c = (%a, %b);
--
You can also use slices to merge one hash into another:
@a{keys %b} = values %b;
Note that items in %b will overwrite items in %a that have the same key.
--
my %c = %a;
map {$c{$_} = $b{$_}} keys %b;
--
%newHash = (%hash1, %hash2); %hash1 = %newHash;
or else ...
@hash1{keys %hash2} = values %hash2;
--
perl -MData::Dumper -le '
$x = { a => 1, b => 2 };
$y = { c => 3, d => 4 };
$x = { %$x, %$y };
print Dumper($x);'
-------------------------------
按哈希值的大小排序
How to sort a hash of hashes by value
对key进行排序
其基本的语法结构为:
sort <排序规则> <排序对象>
若要对keys进行排序则排序对象就是keys,所以最后一项要写成keys %hash。
# 按value排序
## 对hash的keys按hash value排序(按ASCII码排序)
sort { $hash{$a} cmp $hash{$b} } keys %hash
## 对hash的keys按hash value排序(按数字大小排序)
sort { $hash{$a} <=> $hash{$b} } keys %hash
# 按key排序
# 对hash的keys按hash key排序
sort {$a<=>$b} keys %hash
详见如下示例:
按key或value进行排序,原始数据如下:
my $data = {
'Ft3' => {
'Max' => '85',
'Type' => 'text',
'Position' => '17',
'Min' => '40'
},
'Ft2' => {
'Max' => '90',
'Type' => 'json',
'Position' => '11',
'Min' => '60'
},
'Ft1' => {
'Max' => '80',
'Type' => 'text',
'Position' => '19',
'Min' => '40'
},
};
先打印出key(非排序,随机)
my @keys = keys %$data;
foreach my $k (@keys){
say $k;
}
按value中的Position值排序key
$a and $b are the standard place-holders of sort. For each comparison they will hold two keys from the list. In order to compare the Position value of two elements we need to access them using $a and $b and compare the numerical(!) values using the spaceship-operator (<=>).
my @sortedab = sort { $data->{$a}{Position} <=> $data->{$b}{Position} } keys %$data;
my @sortedba = sort { $data->{$b}{Position} <=> $data->{$a}{Position} } keys %$data;
foreach my $k (@sortedab){
say $k;
}
my @maxed = sort {
$data->{$a}{Position} <=> $data->{$b}{Position}
or
$data->{$a}{Max} <=> $data->{$b}{Max}
} keys %$data;
foreach my $k (@maxed){
say $k;
}
-------------------------------
hash的一些数量的判断
问题:hash中是否有健值(k/v)对,有多少个健?
这里就有体现上下文的地方了。
if(%hash)
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.
print "Empty" if(!%hash);
print "Empty" if not(!%hash);
print "Empty" unless(%hash);
上面解决了是否有无的问题,下面来看看在'有'的情况下,有多少数量。
scalar keys %hash
or
keys %hash
my $keys = keys(%hash) ;
"$#%p"这种写法已经不再被支持了。
-------------------------------
Checking for existence of hash subkey but creates key automatic
exists looks for a hash element in a given hash. Your code is autogenerating the hash %{ $hash{output} } and checking if a hash element with key $col is existing in that hash.
if(exists $hash{output}{$col})
changed to
if(exists $hash{output} && exists $hash{output}{$col})
if(exists $hash{output} and exists $hash{output}{$col})
when you ask about the existence of $foo{bar}{fubar}, Perl automatically creates $foo{bar} in order to test whether $foo{bar}{fubar} exists. If you want to prevent this, you have to test to see if $foo{bar} exists, and if it does, then test if $foo{bar}{fubar} exists.
use v5.20;
my $hconf;
my @kwds1=('TMOUT','HISTFILESIZE');
my @kwds2=('TMOUT','HISTSIZE','HISTFILESIZE');
for my $k (@kwds1){
$hconf->{$k}->{cnt}++;
}
for my $k (@kwds2){
#这里就会自动为@kwds2中每个元素在$hconf中创建其key
say "$k\'s Cnt:$hconf->{$k}->{cnt}";
}
say 'Existed.' if exists $hconf->{'HISTSIZE'};
say 'Defined.' if defined($hconf->{'HISTSIZE'});
如果不注意自动创建hash-key,则exists或defined判断会发生误解,导致对结果的误判。
可对更多条件的综合判断来共同决定:
say 'Existed.' if exists $hconf->{'HISTSIZE'}->{cnt};
say 'Defined.' if defined($hconf->{'HISTSIZE'}->{cnt});
-------------------------------
-------------------------------
-------------------------------
-------------------------------
-------------------------------
-------------------------------
-------------------------------