如何设置默认值?

时间:2011-03-17 14:24:47

标签: perl hash

假设我有这样的哈希

my %profile = (
    building            => $p->{account}->{building},
    email               => $p->{account}->{email},
    phone               => $p->{account}->{phone},
    );

$p中的变量在未定义时可以包含各种值。我至少看过undef ~ ''

如何将-1的值分配给例如$profile{building}如果$p->{account}->{building}有这些奇怪的默认值之一?{/ p>

有没有聪明的Perl方法可以做到这一点?

更新:任何值都可以采用任何奇怪的默认值undef ~ ''

5 个答案:

答案 0 :(得分:6)

我会添加一个函数:

my %profile = (
    building            => scrub($p->{account}->{building}),
    email               => scrub($p->{account}->{email}),
    phone               => scrub($p->{account}->{phone}),
    );

并在函数中实现默认过滤逻辑。

或者,更好的是,预先将逻辑应用于$ p,以便您知道$ p具有合理的值。

答案 1 :(得分:4)

所以,如果我理解正确的话,你会有一堆虚假的东西被用作“使用默认值”的标志。我不确定您是否要将所有这些转换为-1或字段特定值。我会假设多个值,只是为了让事情更棘手。

# Make a hash of the wanted values
my %default_values = (
    building => -1,
    email    => 'N/A',
    phone    => 'unlisted',
);

# Make a hash of the values to replace.
# Skip undef, we have to check that separately
my %bogus_values = map {$_ => undef} ('', '~', 0);

# Copy the goodies into your final structure
my  %profile = map { 
    my $val = $p->{account}{$_};
    $val = $default_values{$_}
        if( not defined $val 
            or exists $bogus_values{$_}
        );
    $_ => $val;
} keys %default_values;


# Or copy them another way
my %profile = %default_values;
$profile{$_} = $p->{account}{$_}
    for grep {
        defined $p->{account}{$_}
        and not exists $bogus_values{$_}
    } keys %default_values;

答案 2 :(得分:3)

从Perl 5.10开始,您可以使用smart matching

my @vals = (undef, '~', "");
$profile{building} = $p->{account}{building} ~~ @vals ? -1 : $p->{account}{building};

答案 3 :(得分:1)

如果使用5.10或更高版本,我会使用@ eugene的解决方案。否则......

对于不真实的值(undef,'',0),你可以做

building => $p->{account}->{building} || -1

对于真值,您必须明确检查,可能使用正则表达式:

building => !($p->{account}->{building} =~ m/~|char2|char3/)
            ? $p->{account}->{building}
            : -1

结合这些

building => $p->{account}->{building} || !($p->{account}->{building} =~ 
                                                             m/~|char2|char3/)
            ? $p->{account}->{building}
            : -1

或者,为了使这更简单并且便于测试和重用,您可以将此逻辑提取到子:

sub scrub {
    my $value = shift;

    if (!$value or $value =~ m/~|char2|char3/) {
        return -1;
    }

    return $value;
}

然后

my %profile = (
    building            => scrub( $p->{account}->{building} ),
    email               => scrub( $p->{account}->{email} ),
    phone               => scrub( $p->{account}->{phone} ),
    );

答案 4 :(得分:0)

这类事情将处理FALSE值(例如undef''0'0'或我错过的任何其他内容:

my %profile = (
    building            => $p->{account}->{building} || -1,
    email               => $p->{account}->{email} || 'N/A',
    phone               => $p->{account}->{phone} || -1,
    );

您还可以使用已定义或操作符 //,如果undef位于左侧,则只会使用默认值。


或者照顾其他价值观:

my %bad_values_hash = map { $_ => 1 } ('~', ''); # Put your bad values in here

my %profile = (
    building            => ($bad_values_hash{$p->{account}->{building}} ? -1 : $p->{account}->{building}) // -1,
    email               => ($bad_values_hash{$p->{account}->{email}} ? 'N/A' : $p->{account}->{email}) // 'N/A',
    phone               => ($bad_values_hash{$p->{account}->{phone}} ? -1 : $p->{account}->{phone}) // -1,
    );

(我可以建议改进设计,使其使用更一致的默认值吗?)