[英]Perl, checking various types of hash for empty key values, json
我现在正在为我的函数实现某种模拟。 我在这里有一个小问题。 根据情况,我可以获取不同类型的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 :: 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
。
我不确定我是否正确理解了这个问题,但是假设这是程序需要处理的仅有的两种数据结构类型,这是对它们进行处理的一种方法:
#!/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
引用哈希,并计算键的数目和值为空字符串的值的数目。
以这种方式编写函数,使其遍历参数列表。 然后,您可以将单个哈希\\%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}});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.