如何判断哈希在赋值中是否包含奇数个元素?

sid*_*com 3 perl hash

我怎么能知道这个哈希是否有奇数个元素?

my %hash = ( 1, 2, 3, 4, 5 );
Run Code Online (Sandbox Code Playgroud)

好的,我应该写更多信息.

sub routine {
    my ( $first, $hash_ref ) = @_;
    if ( $hash_ref refers to a hash with odd numbers of elements ) {
        "Second argument refers to a hash with odd numbers of elements.\nFalling back to default values";
        $hash_ref = { option1 => 'office', option2 => 34, option3 => 'fast'  };
    }
    ...
    ...
}


routine( [ 'one', 'two', 'three' ], { option1 =>, option2 => undef, option3 => 'fast' );
Run Code Online (Sandbox Code Playgroud)

rai*_*7ow 7

好吧,我想在这个问题中应该澄清一些术语混淆.

Perl中的哈希总是具有相同数量的键和值 - 因为它基本上是通过键存储某些值的引擎.我的意思是,键值对应该被视为这里的单个元素.)

但我猜这不是真正的问题.我想OP试图从列表中构建一个哈希值(不是数组 - 差别很微妙,但它仍然存在),并得到了警告.

因此,重点是检查列表中将分配给散列的元素数量.它可以像......一样简单

my @list = ( ... there goes a list ... ); 
print @list % 2; # 1 if the list had an odd number of elements, 0 otherwise
Run Code Online (Sandbox Code Playgroud)

请注意,%运算符在列表变量上强制使用标量上下文:它简单而优雅.)

我看到更新,问题略有不同.好吧,让我们谈谈给出的例子,简化一下.

my $anhash = { 
   option1 =>, 
   option2 => undef, 
   option3 => 'fast'
};
Run Code Online (Sandbox Code Playgroud)

看,=>只是一种语法糖; 这项任务可以很容易地改写成......

my $anhash = { 
   'option1', , 'option2', undef, 'option3', 'fast'
};
Run Code Online (Sandbox Code Playgroud)

关键是在第一个逗号后缺少值并且undef 不一样,因为列表(任何列表)在Perl中自动展平.undef可以是任何列表的普通元素,但只会忽略空格.

请注意,如果调用过程中包含无效的散列,则会在调用过程之前引发您关注的警告(如果use warnings已设置).因此,任何引起这种情况的人都应该自己处理它,看看他自己的代码:他们说,早点失败.)

您想使用命名参数,但为缺少的参数设置一些默认值?使用这种技术:

sub test_sub {
  my ($args_ref) = @_;
  my $default_args_ref = {
    option1 => 'xxx',
    option2 => 'yyy',
  };
  $args_ref = { %$default_args_ref, %$args_ref,  };
}
Run Code Online (Sandbox Code Playgroud)

那么你的test_sub可能就像这样调用......

test_sub { option1 => 'zzz' };
Run Code Online (Sandbox Code Playgroud)

... 甚至 ...

test_sub {};
Run Code Online (Sandbox Code Playgroud)


TLP*_*TLP 6

简单的答案是:你得到一个警告:

Odd number of elements in hash assignment at...
Run Code Online (Sandbox Code Playgroud)

假设你没有愚蠢并且发出警告.

硬答案是,一旦完成散列的分配(并发出警告),它就不再是奇怪了.所以你不能.

my %hash = (1,2,3,4,5);
use Data::Dumper;
print Dumper \%hash;

$VAR1 = {
      '1' => 2,
      '3' => 4,
      '5' => undef
    };
Run Code Online (Sandbox Code Playgroud)

如你所见,undef已被插入空白处.现在,您可以检查未定义的值并假设任何现有的未定义值构成散列中的奇数个元素.但是,如果未定义的值是哈希值中的有效值,则会遇到麻烦.

perl -lwe '
    sub isodd { my $count = @_ = grep defined, @_; return ($count % 2) }; 
    %a=(a=>1,2); 
    print isodd(%a);'
Odd number of elements in hash assignment at -e line 1.
1
Run Code Online (Sandbox Code Playgroud)

在这个单行中,函数isodd对已定义的参数进行计数,并返回参数的数量是否为奇数.但正如你所看到的,它仍然会发出警告.