删除数组的Perl哈希中的空字符串

时间:2014-03-28 19:53:23

标签: perl hash

我有这种结构的哈希

{
  a => ['1', '2', '', '5', '6', '7', '8'],
  b => ['1', '2', '3', '6', '7', '8', '9'],
  c => ['2', '', '4', '', '', '8', ''],
}

我需要这样的一些

{
  c => ['2', '4', '8'], 
  a => ['1', '2', '5', '6', '7', '8'], 
  b => ['1', '2', '3', '6', '7', '8', '9']
}

如何删除''值?

4 个答案:

答案 0 :(得分:11)

您可以直接更改values返回的数组引用列表,如perldoc中所述。

use warnings;
my %h = (
  'c' => ['2','','4','','','8',''],
  'a' => ['1','2','','5','6','7','8'],
  'b' => ['1','2','3','6','7','8','9']
);

@$_ = grep defined && length, @$_ for values %h;

如果不应过滤掉undef值,

@$_ = grep !defined || length, @$_ for values %h;

答案 1 :(得分:2)

mpapec已经发布了一个很简洁的答案,但我想我也发布了我的解决方案。

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my %hash = (    c => ['2','','4','','','8',''],
                a => ['1','2','','5','6','7','8'],
                b => ['1','2','3','6','7','8','9'],
        );

for my $key (keys %hash) {
        my @temp_array = ();
        for my $element ( @{$hash{$key}} ) {
                if ( $element ne "" ) { # only remove empty strings
                        push @temp_array, $element;
                }

        }
        $hash{$key}=\@temp_array;
}

print Dumper %hash;

这会遍历整个数据结构,如果您需要访问其他元素,这可能会有所帮助。这是输出:


$VAR1 = 'c';
$VAR2 = [
          '2',
          '4',
          '8'
        ];
$VAR3 = 'a';
$VAR4 = [
          '1',
          '2',
          '5',
          '6',
          '7',
          '8'
        ];
$VAR5 = 'b';
$VAR6 = [
          '1',
          '2',
          '3',
          '6',
          '7',
          '8',
          '9'
        ];

答案 2 :(得分:2)

到目前为止,您所看到的答案都没有考虑哈希值可能是除简单字符串或数字之外的其他任何内容。

虽然这可能适合您的数据,但一般来说这不是一个安全的假设。

此示例修改了哈希值,仅删除空字符串值并保留其他所有内容。

请注意,即使可能需要安装,Data::Dump通常是比Data::Dumper更好的选择,如此处所示。

use strict;
use warnings;

my @alpha = ('a' .. 'm');

my $hash = {
  a => ['1', '2', '', '5', '6', '7', '8'],
  b => ['1', '2', '3', '6', '7', '8', '9'],
  c => ['2', '', '4', '', '', '8', ''],
  d => ['5', '', '6', '', undef, '22', '', 'aa', -51.2, \@alpha],
};

for my $list (values %$hash) {
  for (my $i = $#{$list}; $i >= 0; --$i) {
    my $item = $list->[$i];
    splice(@{$list}, $i, 1) if defined $item and $item eq '';
  }
}

use Data::Dump;
dd $hash;

<强>输出

{
  a => [1, 2, 5 .. 8],
  b => [1, 2, 3, 6 .. 9],
  c => [2, 4, 8],
  d => [5, 6, undef, 22, "aa", -51.2, ["a" .. "m"]],
}

答案 3 :(得分:0)

因为操作系统希望得到一个哈希值,所以这是一个很好的快速解决方案:)

use strict;
use warnings; 
use Data::Dumper;
use feature 'say';

my %h = (
  'c' => ['2','','4','','','8',''],
  'a' => ['1','2','','5','6','7','8'],
  'b' => ['1','2','3','6','7','8','9']
);

foreach my $keys ( keys %h) {
    $h{$keys} = [grep { length $_ } @{$h{$keys}}];
}

say Dumper \%h;