为真理或存在检查Perl哈希键是否更好?

Joe*_*Joe 15 perl hash

当分配给只是键的哈希(其中值不是真正需要的)时,它是否更可取,说:

$hash{$new_key} = "";
Run Code Online (Sandbox Code Playgroud)

或者说:

$hash{$new_key} = 1;
Run Code Online (Sandbox Code Playgroud)

一个必须要检查一个键exists,另一个允许你说:

if (exists $hash{$some_key})
Run Code Online (Sandbox Code Playgroud)

要么

if ($hash{$some_key})
Run Code Online (Sandbox Code Playgroud)

我认为分配1会更好,但这有什么问题吗?它甚至重要吗?

bri*_*foy 16

这取决于您是否需要存在密钥或具有真正的价值.测试你需要的东西.如果你只是使用哈希来查看列表中是否有东西,那么exists()就是你要走的路.如果您正在做其他事情,检查值可能是要走的路.


Chr*_*ons 11

当不需要这些值时,你会经常看到这个成语:

my %exists;
$exists{$_}++ for @list;
Run Code Online (Sandbox Code Playgroud)

具有将其设置为1的效果.

  • 好吧,它将它设置为密钥出现在@list中的次数. (7认同)
  • 在最近的perlsyn文档中,它说:"当用作数字时,'undef'被视为0; [...]如果启用警告,只要将'undef'视为字符串,就会通知您未初始化的值嗯,通常.[...]运算符,如'++',' - ','+ =',' - ='和'.=',对未定义的左值运算,如:我的$ a; $ a ++;也总是免于这样的警告." 不知道这种行为有多远,但也许有人可以查看旧版本的perlsyn文档来查找... (2认同)

Kin*_*ong 9

如果你正在尝试保存内存(通常只有你有一个非常大的哈希值才有意义),你可以使用undef作为值并测试它的存在.Undef实现为单例,因此数千个undef都只是指向同一个值的指针.将每个值设置为空字符串或1将为每个元素分配不同的标量值.

my %exists;
@exists{@list} = ();
Run Code Online (Sandbox Code Playgroud)

鉴于您后来对您的预期用途的评论,这是我多次见过和使用的习语:

my %seen;
while (<>) {
    next if $seen{$_}++; # false the first time, true every successive time
    ...process line...
}
Run Code Online (Sandbox Code Playgroud)

  • 它在此列表上下文中完成相同的操作,因为左侧的元素多于右侧的元素.这里发生的事情与你写"($ foo,$ bar)=(1);"时会发生同样的事情.$ foo获得1而$ bar获得undef.从概念上讲,Perl使用足够的"ghost"undefs扩展了赋值的右侧以填充左侧.话虽如此,我几乎总是使用$ exists {$ _} ++成语 - 只是为了节省一些调试时间.不必记住$ exists {$ foo}是否存在但未定义更容易. (2认同)