2

I have a hash with this structure

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

And I need some like this

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

How can I delete the '' values?

4
  • This is pretty basic Perl, have you looked at any tutorials of Hashes of Hash references? Commented Mar 28, 2014 at 19:57
  • Hi Hunter.I do. And I dont find the solution, not because not exist, maybe because I dont finish to understand the hash concept. Im begginer with Perl and I certainly would like to spending more time to the documentation. Unfortunately time requirements in other work tasks prevent me from doing so. I try to do what I can before asking something more, but hey, sometimes I can not. Commented Mar 28, 2014 at 20:15
  • @christian: I think your idea of Stack Overflow is wrong. We are here to help when a programmer has tried their best but is still stuck with a problem he cannot resolve. It is not fair to ask for help when you are faced with a question that is simply beyond your capabilities, either because of your inexperience or because you cannot find the time. In short, you are welcome to ask for a hint, but please don't ask for your work to be done for you. Commented Mar 28, 2014 at 22:55
  • Hi Borodin. I guess that I do not explain well in my last comment. It's true, Im not programmer im biologist, but this questions it's not part of my work. I try to learn in my free time to improve mi skills not to resolve my laboral issues which usually are restricted to assay tubes. And I arrive to StackOverflow because a programmer friend talk me about the site and he encourage me to ask here. Im sorry if I cause a bad impression. Commented Mar 30, 2014 at 1:59

4 Answers 4

11

You can directly change list of array references returned by values as described in 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;

and in the case that undef values should not be filtered out,

@$_ = grep !defined || length, @$_ for values %h;
Sign up to request clarification or add additional context in comments.

11 Comments

Not sure who downvoted you or why, but I ran your code and it works for me. Hopefully works for op too!
Thanks a lot mpapec. Work perfect.
Please comment when down voting.
If the warnings pragma is in place as it should be then length will throw a warning if any element of the array is undef.
@mpapec You should plan on writing a blog or something where you explain your idiomatic way of writing perl. Will prove very useful for newbies like me. :)
|
2

mpapec has already posted a nice succinct answer, but I figured I post my solution too.

#!/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;

This traverses the whole data structure and maybe that will help if you need to access the elements for other things. Here's the output:


$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 Comments

its a bit overhead with that temp array. its not necassary.
@Matt: Using Data::Dumper (and Data::Dump) it is best to pass a reference to hashes and arrays. Otherwise you will get the contents of the variable expressed as a list of independent scalar values. Try print Dumper \%hash in your code and you will see the difference.
2

None of the answers you have seen so far consider the possibility that the hash values may be anything other than simple strings or numbers.

While that may be appropriate to your data, it isn't a safe assumption in general.

This example modifies the hash in place, removing only empty string values and preserving everything else.

Note that, even though it may need to be installed, Data::Dump is usually a better choice than Data::Dumper, as shown here.

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;

output

{
  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 Comments

Could you please explain why Data::Dump is usually a better choice than Data::Dumper.
@Chris: Because it formats the data structure in a much more readable way. It is written by Gisle Aas, the author of the extraordinary LWP suite, and he says in the documentation "The Data::Dump module grew out of frustration with Sarathy's in-most-cases-excellent Data::Dumper". Try it: I am sure you will like it.
+1 as strictly answering to question IE: to not remove undefined values!
0

since the op wanted to get a hash back, here is a quick solution which works fine :)

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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.