Home > database >  Perl: grep from multiple arrays at once
Perl: grep from multiple arrays at once

Time:07-08

I have multiple arrays (~32). I want to remove all blank elements from them. How can it be done in a short way (may be via one foreach loop or 1-2 command lines)?

I tried the below, but it's not working:

    my @refreshArrayList=("@list1", "@list2", "@list3","@list4", "@list5", "@list6" , "@list7");
    foreach my $i (@refreshArrayList) {
        $i = grep (!/^\s*$/, $i);
    }

Let's say, @list1 = ("abc","def","","ghi"); @list2 = ("qwe","","rty","uy", "iop"), and similarly for other arrays. Now, I want to remove all blank elements from all the arrays.

Desired Output shall be: @list1 = ("abc","def","ghi"); @list2 = ("qwe","rty","uy", "iop") ### All blank elements are removed from all the arrays.

How can it be done?

CodePudding user response:

You can create a list of list references and then iterator over these, like

for my $list (\@list1, \@list2, \@list3) {
     @$list = grep (!/^\s*$/, @$list);
}

Of course, you could create this list of list references also dynamically, i.e.

my @list_of_lists;
push @list_of_lists, \@list1;
push @list_of_lists, \@list2;
...
for my $list (@list_of_lists) {
     @$list = grep (!/^\s*$/, @$list);
}

CodePudding user response:

@$_ = grep /\S/, @$_  for @AoA;   # @AoA = (\@ary1, \@ary2, ...)

Explanation. In a foreach loop, the variable set to each element in turn as the list is iterated over ("topicalizer") is an alias to those elements. So changing it changes the element. From perlsyn

If VAR is omitted, $_ is set to each value.

If any element of LIST is an lvalue, you can modify it by modifying VAR inside the loop.

In our case $_ is always an array reference, and then the underlying array is rewritten by dereferencing it (@$_) and assigning to it the output list of grep, consisting only of elements that have at least one non-space character (/\S/).

Finally, I use the statement modifier, "reversing" the usual for loop syntax

The for(each) modifier is an iterator: it executes the statement once for each item in the LIST (with $_ aliased to each item in turn).

It is mostly equivalent to a "normal" for loop, with the most notable differences being that no scope is set, and that we can have only one statement under it (but then again, that can be a do block).

  • Related