【问题标题】:Compare and edit underlying structure in hash比较和编辑哈希中的底层结构
【发布时间】:2012-10-01 13:37:22
【问题描述】:

我有一个复杂结构的哈希,我想执行搜索和替换。第一个哈希如下:

$VAR1 = {
  abc => { 123 => ["xx", "yy", "zy"], 456 => ["ab", "cd", "ef"] },
  def => { 659 => ["wx", "yg", "kl"], 456 => ["as", "sd", "df"] },
  mno => { 987 => ["lk", "dm", "sd"] },
}

我想迭代地搜索所有 '123'/'456' 元素,如果找到匹配项,我需要比较子层,即['ab','cd','ef']['as','sd','df'],在这种情况下, 只保留带有 ['ab','cd','ef'] 的那个。所以输出如下:

$VAR1 = {
  abc => { 123 => ["xx", "yy", "zy"], 456 => ["ab", "cd", "ef"] },
  def => { 659 => ["wx", "yg", "kl"] },
  mno => { 987 => ["lk", "dm", "sd"] },
}

所以删除是基于子结构,而不是索引。怎么做到呢?感谢您的帮助!

假设我将声明要保留的值,即我将保留 456 => ["ab", "cd", "ef"] 基于预先声明的值 ["ab", "cd ", "ef"] 并在其他任何地方删除 456 的任何其他实例。搜索必须针对每个键。因此代码将通过哈希,首先取 123 => ["xx", "yy", "zy"] 并将其与哈希其余部分的键进行比较,如果未找到匹配项,则不执行任何操作。如果找到匹配项,例如 456 => ["ab", "cd", "ef"],它将比较两者,正如我所说,在匹配的情况下,带有 [" ab", "cd", "ef"] 将被保留,它将保留 456 => ["ab", "cd", "ef"] 并丢弃散列中其他任何位置的 456 的任何其他实例,即它将在这种情况下删除 456 => ["as", "sd", "df"]。

【问题讨论】:

  • 看看perldsc.. 都是这些东西而已.. 特别是hashes of hashes
  • 您应该指定应该如何决定要保留哪个条目。
  • 你让我看这个。我只能说“什么?”
  • 请教你的智慧@ikegami...:) 我已经编辑了这个问题。 'what' 被定义为 456 => ["ab", "cd", "ef"]。现在我的问题是怎么做?

标签: perl search hash structure


【解决方案1】:

这是一个使用智能匹配运算符来执行数组比较的解决方案:

更新: 正如 Borodin 指出的那样,我的原始代码是错误的。这是固定版本。

更新 2: 将其更改为根据哈希结构选择要保留的值。

my $VAR1 = {
  abc => { 123 => ["xx", "yy", "zy"], 456 => ["ab", "cd", "ef"] },
  def => { 659 => ["wx", "yg", "kl"], 456 => ["as", "sd", "df"] },
  mno => { 987 => ["lk", "dm", "sd"] },
};

my %keep_values = (
    '456' => ['ab','cd','ef']
);

foreach my $outer_key (keys %$VAR1)
{
    foreach my $keepers (keys %keep_values)
    {
        if (exists $VAR1->{$outer_key}{$keepers} and 
            #use the smart match operator to compare arrays.
            !(@{$VAR1->{$outer_key}{$keepers}} ~~ @{$keep_values{$keepers}}))
        {
            delete $VAR1->{$outer_key}{$keepers};
        }
    }   
}

有关智能匹配运算符的更多信息,请参阅perlop

【讨论】:

  • 非常感谢 dan1111,问题是,我需要整个东西都是动态的,所以我不能定义 $match_key 或 @match_array。它需要独立于我给出的任何输入......
  • 那么你必须澄清['ab','cd','ef']的特别之处,它让你选择它而不是['as','sd','df']。这远非显而易见
  • 这是非常糟糕的代码。您没有use strictuse warnings,也没有声明$outer_hash。您的变量$outer_hash 也设置为%$VAR1 的每个键,即abcdefmno,所以$outer_hash->{$match_key} 没有意义
  • @Borodin,好吧,假设我只保留 ['ab','cd','ef'] 并删除所有其他重复的实例,但我仍然必须通过所有'456' 和 '123' 等键......
  • @Borodin,这是一个脑残的错误。我不知道它是怎么发生的;我实际上测试了这个(!),但我一定是看错了什么。至于strictwarnings,是的,我用过这些,但这是摘录,不是完整的程序。我在$outer_hash 中添加了my 声明,尽管由于Perl 对循环变量的隐式本地化,这并不是绝对必要的。
猜你喜欢
  • 2011-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 1970-01-01
  • 2017-11-08
  • 1970-01-01
相关资源
最近更新 更多