我现在正在实现某种模拟我的功能。我在这里有一个小问题。根据情况,我可以得到不同类型的JSON以及其他类型的哈希。它可以是一个简单的哈希,具有空键的值,也可以是带有空值或没有空值的哈希数组。
my %ch1 = (
"a" => "",
"b" => "",
"c" => ""
);
my %ch2 = (
"tab" => [
{
"a" => 11,
"b" => 22,
"c" => 33
},
{
"a" => 44,
"b" => 55,
"c" => 66
}
]
);
我需要制作一个函数来检查两种类型的哈希,计数空值并与哈希的键进行比较。
这个有点适合第一个哈希,但我不知道如何使它在不进行硬编码的情况下为两种哈希工作。
my $tck = 0;
for (keys %ch1){
if ($ch1{$_} eq ""){
print "'$ch1{$_}'n";
$tck++;
}
}
if ($tck == scalar keys %ch1){
# do something
}
有什么建议?
您可以使用data :: visitor ::回调来做到这一点。这是一个非常直接的实现,只要您的数据结构中没有其他包含空字符串的东西。
模块在数据结构中访问每个项目,并在这些项目上调用用户定义的回调。它将为每个参考文献中的每个参考和每个值做到这一点。
use strict;
use warnings;
use Data::Visitor::Callback;
my %ch1 = (
"a" => "",
"b" => "",
"c" => ""
);
my $empty_strings;
my $v = Data::Visitor::Callback->new(
value => sub {
++$empty_strings if $_ eq q{}; # q{} is like '' but easier to read
},
);
$v->visit( %ch1 );
print $empty_strings;
这将输出3
,因为输入哈希中有三个空字符串。请注意,它想要哈希参考,而不是哈希本身。
您可以通过更复杂的数据结构。布局并不重要。我在您的第二个示例中添加了一个空字符串,以显示其有效。
use strict;
use warnings;
use Data::Visitor::Callback;
my $empty_strings;
my $v = Data::Visitor::Callback->new(
value => sub {
++$empty_strings if $_ eq q{};
},
);
my %ch2 = (
"tab" => [
{
"a" => 11,
"b" => 22,
"c" => 33
},
{
"a" => '',
"b" => 55,
"c" => 66
}
]
);
$v->visit( %ch2 );
print $empty_strings;
在这种情况下,输出为 1
。
由于没有简单的方法可以区分它所看到的值是钥匙还是值,因此此实现也将计算以下内容。因此,它不是完美的,但应该适合您显示的数据类型。
my %fail = (
"" => "foo", # one
"b" => [ "", "" ], # two, three
);
此数据结构将产生$empty_strings
的3
。
我不确定我是否正确理解了问题,但是假设这些数据是您程序需要处理的两种类型的数据结构,那么这是一种与他们:
#!/usr/bin/env perl
use strict;
use warnings;
use List::MoreUtils qw( all none );
my %ch1 = (
"a" => "",
"b" => "",
"c" => ""
);
my %ch2 = (
"tab" => [
{
"a" => 11,
"b" => 22,
"c" => 33
},
{
"a" => 44,
"b" => 55,
"c" => 66
}
]
);
use YAML::XS;
for my $h ( (%ch1, %ch2) ) {
print Dump n_keys_empty_values( $h );
}
sub n_keys_empty_values {
my $h = shift;
if ( all { ref } values %$h ) {
return [ map { my $v = $_; map count_empty_values( $_ ), @$v } values %$h ]
}
elsif ( none { ref } values %$h ){
return [ count_empty_values( $h ) ];
}
else {
die "Unexpected data structuren";
}
}
sub count_empty_values {
my $h = shift;
[ scalar keys %$h, scalar grep $_ eq '', values %$h ];
}
输出:
---- - 3 -3--- - 3 -0 - 3 -0
n_keys_empty_values
的返回值是对数组引用数组的引用。外部阵列的大小对应于传递的内部哈希数。count_empty_values
参考哈希,并计算空字符串的键和值数量。
以这种方式写下您的功能,它在参数列表中迭代。然后,您可以将单个哈希%ch1
或哈希列表 @{$ch2{tab}}
传递给该功能。
#! /usr/bin/perl
use strict;
use warnings;
my %ch1 = (
"a" => "",
"b" => "",
"c" => ""
);
my %ch2 = (
"tab" => [
{
"a" => 11,
"b" => 22,
"c" => 33
},
{
"a" => 44,
"b" => 55,
"c" => 66
}
]
);
my %ch3 = (
"tab" => [
{
"a" => '',
"b" => '',
"c" => ''
},
{
"a" => '',
"b" => '',
"c" => ''
}
]
);
sub fun
{
for (@_) {
my %ch = %{$_};
my $tck = 0;
for (keys %ch){
if ($ch{$_} eq ""){
print "'$ch{$_}'n";
$tck++;
}
}
if ($tck == scalar keys %ch){
print "do somethingn";
}
}
}
fun (%ch1);
fun (@{$ch2{tab}});
fun (@{$ch3{tab}});