【问题标题】:How can I delete duplicate values across arrays stored in hash?如何删除存储在哈希中的数组中的重复值?
【发布时间】:2015-08-29 03:46:19
【问题描述】:

我有以下哈希:

my %HASH = (
    'List1' =>  [ 'the', 'red', 'cat', 'jumps' ],
    'List2' =>  [ 'the', 'brown', 'fox', 'jumps' ],
    'List3' =>  [ 'a', 'red', 'fox', 'jumps' ],
);

我想删除这些数组中的重复元素,以便只保留唯一元素。所需的输出如下:

my %HASH = (
    'List1' =>  [ 'cat' ],
    'List2' =>  [ 'brown' ],
    'List3' =>  [ 'a' ],
);

换句话说,如果一个元素同时出现在 List1 和 List2 中,则应该从两个列表中删除它。

我已尝试执行以下操作:

use strict;
use warnings;
use diagnostics;
use Data::Dumper;

foreach my $key ( keys %HASH )  {

    foreach ( @{$HASH{$key}} )  {

        if(exists($HASH{$key})){
            @{$HASH{$key}} = delete($HASH{$key});
        }
    }
}

print Dumper(\%HASH);

这似乎没有做任何事情,哈希保持原样。我对 Perl 还是很陌生,所以我不确定我哪里出错了。但是 Perldoc 表示无论如何都不推荐在数组值上调用 exists,因此也欢迎任何使用非存在的东西的解决方案!

【问题讨论】:

    标签: arrays perl hash


    【解决方案1】:
    use strict;
    use warnings;
    
    my %hash = (
        'List1' =>  [ 'the', 'red', 'cat', 'jumps' ],
        'List2' =>  [ 'the', 'brown', 'fox', 'jumps' ],
        'List3' =>  [ 'a', 'red', 'fox', 'jumps' ],
    );
    
    # first, we count all words
    my %count;
    for my $words (values %hash) {
        for my $word (@$words) {
            $count{$word}++;
        }
    }
    
    # Now, we filter the words with `grep` so that only
    # those remain which were found once
    for my $words (values %hash) {
        @$words = grep { $count{$_} == 1 } @$words;
    }
    
    use Data::Dump;
    dd \%hash;
    

    输出:

    { List1 => ["cat"], List2 => ["brown"], List3 => ["a"] }
    

    【讨论】:

    • 正确而优雅。我会编写相同的代码,但是这个 mapgrep 和语句修饰符 for@$_ 对于 Perl 初学者来说可能相当混乱——你可能想用更多解释重写一个更明确的形式的答案(或者我会这样做,如果你同意的话)。
    • @amon 写掉。 :) 是的,这对于初学者来说可能太危险了,但是不扔在那里太有趣了。随意编辑(始终欢迎),或者只是发布您自己的更受教的答案,我很乐意为您投票。
    • 我确实希望能解释一下@$_ 在这里的含义:) 但是这个答案很好用,尽管有点令人困惑!
    • @kormak Amon 的编辑版本与我之前的代码完全相同。这个版本只是使用命名变量而不是稍微过度使用本地化的$_。对于您的问题,@$_ 等同于@$words。因此,在这种情况下,我们正在遍历该数组的值(通过引用 $words 访问)并仅分配回那些唯一的值。
    • @Miller 感谢您的解释!这个版本确实更容易阅读:)
    猜你喜欢
    • 2023-04-09
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多