我现在正在为我的功能实现某种模拟。我在这里有一点问题。根据情况,我可以获得不同类型的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
}
有什么建议吗?
答案 0 :(得分:3)
您可以使用Data::Visitor::Callback来执行此操作。只要数据结构中没有其他包含空字符串的内容,它就是一个非常简单的实现。
模块访问数据结构中的每个项目,并在这些项目上调用用户定义的回调。它将为那些参考中的每个参考和每个值做到这一点。
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
的数量。
答案 1 :(得分:0)
我不确定我是否正确理解了这个问题,但假设这些是您的程序需要能够处理的两种类型的数据结构,这里有一种方法可以解决它:
#!/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 structure\n";
}
}
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
接受对散列的引用,并计算键数和空字符串值。
答案 2 :(得分:0)
以这种方式编写函数,它遍历参数列表。然后,您可以将单个散列\%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 something\n";
}
}
}
fun (\%ch1);
fun (@{$ch2{tab}});
fun (@{$ch3{tab}});