perl,检查各种类型的哈希是否是否为空钥匙值,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 ::回调来做到这一点。这是一个非常直接的实现,只要您的数据结构中没有其他包含空字符串的东西。

模块在数据结构中访问每个项目,并在这些项目上调用用户定义的回调。它将为每个参考文献中的每个参考和每个值做到这一点。

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_strings3

我不确定我是否正确理解了问题,但是假设这些数据是您程序需要处理的两种类型的数据结构,那么这是一种与他们:

#!/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}});

相关内容

最新更新