如果发现重复,请删除Perl哈希值



我需要一个快速帮助,我正在Unix服务器中生成一些命令,并从这些命令中创建一个散列。

问题是大多数时候,有重复的值即将到来,我想从这些哈希中删除任何重复的值。

这里有一个例子:

[randy@server04 ~/scripts]$ perl snmpperl.pl 
$VAR1 = {
    '1b' => [
        'abc_pl',
        'abc_pl',
        'abc_pl',
        'xyz_pl',
        'xyz_pl',
    ],
    '1a' => [
        'abc_pl',
        'abc_pl',
        'abc_pl',
        'abc_pl',
        'xyz_pl',
        'xyz_pl',
    ]

我需要哈希为:-

$VAR1 = {
    '1b' => [
        'abc_pl',
        'xyz_pl',
    ],
    '1a' => [
        'abc_pl',
        'xyz_pl',
    ]

这是一个相对常见的Perl习惯用法,实际上在FAQ中得到了解决,您可以在任何安装了Perl的系统上键入perldoc -q duplicate来找到它。

以下是对常见问题解答中表达的想法的改编:

use strict;
use warnings;
use Data::Dumper;
my %hash = (
  '1b' => [ 'abc_pl', 'abc_pl', 'abc_pl', 'xyz_pl', 'xyz_pl', ],
  '1a' => [ 'abc_pl', 'abc_pl', 'abc_pl', 'abc_pl', 'xyz_pl', 'xyz_pl', ],
);
foreach my $v ( values %hash ) {
  my %seen;
  @$v = grep { !$seen{$_}++ } @$v;
}
print Dumper %hash;

这是通过跟踪给定哈希键的子数组中的任何给定元素以前是否被看到来实现的。如果没有,请通过grep过滤器。否则,不要发送。最后,所有构建到新结构中的都是数组元素的单个实例。

一个细微之处值得一提;foreach循环中的"it"变量将成为它所代表的元素的别名。因此,在这种情况下,对于循环的每次迭代,$v都会对一个散列元素进行别名,该散列元素的值包含匿名数组引用。我们只需将匿名数组ref的内容替换为已消除重复的元素。

use List::MoreUtils 'uniq';
@$_ = uniq @$_ for values %hash;

List::MoreUtils 替换uniq

sub uniq (@) {
    my %seen;
    grep !$seen{$_}++, @_;
}

最新更新