【问题标题】:perl hashref lookup function always returning default valueperl hashref 查找函数总是返回默认值
【发布时间】:2016-07-22 14:16:11
【问题描述】:

当我在 hashref 中查找键和值时,我有以下函数应该返回 true 或 false。我确定我错过了什么,但是什么?

如果找到我们搜索的键值字符串,该函数应该返回 true 或 false。

#!/usr/bin/perl
use warnings;
use strict;
my $structure = {
    Key1 => {
           Key4 => "findme",
           Key5 => 9,
           Key6 => 10,
         },
    Key2 => {
           Key7 => "abc",
           Key8 => 9,
             },
 };

sub lookup_key_value
{
    # Arguments are a hash ref and a list of keys to find
    my($hash,$findkey, $findvalue) = @_;

        # Loop over the keys in the hash
        foreach my $hashkey ( keys %{$hash})
        {

            # Get the value for the current key
            my $value = $hash->{$hashkey};

            # See if the value is a hash reference
            if (ref($value) eq 'HASH')
            {
                    # If it is call this function for that hash
                    &lookup_key_value($value,$findkey,$findvalue);
            }

            if ( ($findkey =~ m/^$hashkey$/) && ( $value =~ m/^$findvalue$/) )
            {
                print "$findkey = $hashkey, $value = $findvalue\n";
                return (0);
            }
        }
        return (1);
}

if ( &lookup_key_value($structure,"Key7","abcX") )
{
    print "FOUND !\n";
} else {
    print "MISSING !\n";
}

【问题讨论】:

    标签: perl hash hashref


    【解决方案1】:
    1. 这个$findkey =~ m/^$hashkey$/应该是$hashkey =~ m/^$findkey$/
    2. 当找到匹配的键/值对时返回 0,这在 Perl 中转换为 false,而当未找到匹配的键/值对时返回 1 (true)。为什么?颠倒这个逻辑。要返回 false,请使用简单的 return;,不带任何参数。

    【讨论】:

    • 感谢提示,我修改相关代码为: if ( ($hashkey eq $findkey) && ( $value eq $findvalue) ) { print "KEY $findkey = $hashkey, VALUE $值 = $findvalue\n";返回(1); } } 返回; if ( &lookup_key_value($structure,"Key7","abc") ) { print "FOUND !\n"; } else { 打印“失踪!\n”;但是我仍然得到“失踪!”修改查找函数的参数时。谢谢
    • 还有一件事:调用 Perl 中的函数时应该不带 & 字符(除了一些有限的用例)。
    • 对。您需要将递归函数调用的结果向上传递,例如:将lookup_key_value($value,$findkey,$findvalue); 更改为if (lookup_key_value($value,$findkey,$findvalue)) { return 1; }
    • 谢谢 Bart,在进行了您上面建议的更改后,它按预期工作。您为我节省了几个额外的故障排除时间!你太棒了!
    【解决方案2】:

    您将散列用作键/值对数组,而不是使用内容寻址功能,这可以使其更快、更简洁。无需检查每个哈希的所有元素

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    my $structure = {
        Key1 => { Key4 => "findme", Key5 => 9, Key6 => 10 },
        Key2 => { Key7 => "abc",    Key8 => 9 },
    };
    
    sub lookup_key_value {
    
        my ( $hash, $findkey, $findvalue ) = @_;
    
        my $val = $hash->{$findkey};
    
        if ( not ref $val ) {
            return 1 if defined $val and $val eq $findvalue;
        }
    
        for $val ( grep { ref eq 'HASH' } values %$hash ) {
            return 1 if lookup_key_value( $val, $findkey, $findvalue );
        }
    
        return;
    }
    
    print lookup_key_value( $structure, 'Key7', 'abcX' ) ? "FOUND !\n" : "MISSING !\n";
    

    输出

    MISSING !
    

    【讨论】:

    • 有趣的方法,我不会想到以这种方式使用 grep。谢谢
    猜你喜欢
    • 2014-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-19
    • 2021-07-20
    • 1970-01-01
    相关资源
    最近更新 更多