【问题标题】:Hashes: testing a key哈希:测试密钥
【发布时间】:2017-03-23 23:13:18
【问题描述】:

程序将一个非常大的字典式 TXT 文件读入散列。有时,键的小写版本更可取。我下面的解决方案很笨拙,因为即使我们已经知道 lc 版本存在,它也会搜索两次:

if ( exists $hash{ lc $key } ) {
   $key = lc $key;
}
if ( exists $hash{ $key } ) {
    # lot of code involving $key
}
else {
    # the key doesn't exist, other code
}

有没有办法避免两次exists 测试?如果lc $key 存在,我想对它执行与第二个if 相同的代码,但我需要知道$key 使用哪个版本,lc 与否。我希望将其压缩为一对if-else

知道有效密钥的大小写对于程序的其余部分很重要,因为它用于在另一个哈希中查找信息。

【问题讨论】:

  • 这是否意味着您可以同时将fooFOO 作为同一哈希中的键?
  • 是的。这是名称和单词的散列。有些名字也是词。因此,如果用户提供“John”并且“john”也存在,那么“john”就是我所追求的。然后,我使用“john”搜索另一个哈希的值,并提供与“john”关联但不与“John”关联的该哈希的所有键。
  • 在将键读入搜索索引时对其进行标准化,但这可能不值得。与较大的费用相比,两次哈希查找并不昂贵。或者把文件放到SQLite中,使用SQL(这样可以解决很多问题)。
  • Hash1 有:John - WORD1,john - WORD2。 Hash1 中的每个键都作为 Hash2 中的值存在。翻译 1 - 约翰,翻译 2 - 约翰,翻译 3 - 约翰。但我只挑选“约翰”的翻译,而不是“约翰”的翻译。因此需要保留大小写。我希望能更好地解释它!我不知道哈希查找不受哈希大小的影响,所以也许我的问题毕竟不是问题:)
  • 重新打开。 OP 不希望使用不区分大小写的键的哈希。

标签: perl hash


【解决方案1】:
if ( my ($real_key) = grep { exists($hash{$_}) } lc($key), $key ) {
   ...
} else {
   ...
}

my $real_key =
     exists($hash{ lc($key) }) ? lc($key)
   : exists($hash{ $key     }) ? $key
   : undef;

if (defined($real_key)) {
   ...
} else {
   ...
}

当然,它仍然会搜索两次,但那又怎样?您可以使用 List::Utils 的 first,但我认为用子调用替换哈希查找实际上会减慢代码速度!

【讨论】:

  • 在哈希上使用exists 两次不是性能问题吗?我一直在寻找替代方案,因为哈希有超过 250,000 个条目。
  • @Erik Olson,哈希查找是 O(1),这意味着它们不受哈希大小的影响。
  • 两个哈希查找可能比一个棘手的单行查找更容易阅读和处理更快。只是为了我自己的启发,您的示例中的grep 是否在一个步骤中返回小写$key(如果有效)还是每次都检查普通的旧$key?谢谢!
  • 我认为您正在尝试将您的代码与我的代码进行比较(即使两者都进行了两次哈希查找),我实际上发现grep 的一个微不足道的使用比非常不寻常的代码结构和变量重用要清晰得多你有。如果我看到你的代码,我会做出双重考虑(“这真的正确吗?”)。我在我的回答中添加了一个不使用grep 的解决方案,但你真的应该开始练习使用它。
【解决方案2】:

您可以使用来自List::Utilfirst。它将返回代码块的结果为真值的第一个列表元素,如果代码块从不返回真值,则返回 undef

use List::Util qw(first);

$key = first { exists($hash{$_}) } lc($key), $key;

if (defined($key)) {
    # ...
}

【讨论】:

    【解决方案3】:

    你也可以这样做:

    $key = do { my $temp = lc $key; exists $hash{$temp} ? $temp 
          : ( exists $hash{$key} ? $key : undef) };
    
    if ( defined $key ) {
        # lot of code involving $key
    }
    else {
        # the key doesn't exist, other code
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-30
      • 1970-01-01
      • 2018-04-01
      相关资源
      最近更新 更多