Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I grep through an array, while filtering out matches?

Tags:

arrays

perl

Is there a quick and easy way to grep through an array finding the elements satisfying some test and remove these from the original array?

For example I would like

@a = (1, 7, 6, 3, 8, 4);
@b = grep_filter { $_ > 5 } @a;

# now @b = (7, 6, 8)
# and @a = (1, 3, 4)

In other words, I want to split an array into two arrays: those which match and those which do not match a certain condition.

like image 461
Juan A. Navarro Avatar asked Jul 15 '11 11:07

Juan A. Navarro


People also ask

How do I get the number of matching lines in grep?

You can make grep display the line number for each matching line by using the -n (line number) option. The line number for each matching line is displayed at the start of the line. To reduce the number of results that are displayed, use the -m (max count) option.

How do I grep an array in a text file?

If you have to use an array for some reason, things are more complicated. You can't just do grep "$ {array [*]}" Textfile because "$ {array [*]}" will expand to the list of elements in the array separated by a space: And that means "grep for foo bar baz in the file file ". What you want to do is to grep for foo, or bar, or baz.

How to use an array filter in JavaScript?

We can use an array filter in JavaScript to make the code even shorter and easier to understand. In the below example, we will create an array of people objects and filter out the objects with an age greater than 18. Until now, we have seen examples where we were defining a function while declaring the array.filter method.

How do I grep for a specific pattern in a file?

What you want to do is to grep for foo, or bar, or baz. This can be done using the -E option of grep and joining the patterns you want to search for with |: On the whole, it's simply better, quicker and easier to use the file and forget about the array.


3 Answers

Know your libraries, mang.

use List::MoreUtils qw(part);
part { $_>5 } (1, 7, 6, 3, 8, 4)

returns

(
    [1, 3, 4],
    [7, 6, 8],
)
like image 182
daxim Avatar answered Oct 01 '22 07:10

daxim


my @a = (1, 7, 6, 3, 8, 4);
my (@b, @c);    

push @{ $_ > 5 ? \@b : \@c }, $_ for @a;
like image 44
Eugene Yarmash Avatar answered Oct 01 '22 08:10

Eugene Yarmash


Using libraries is good, but for completeness, here is the function as specified in the question:

sub grep_filter (&\@) {
    my ($code, $src) = @_;
    my ($i, @ret) = 0;
    local *_;
    while ($i < @$src) {
        *_ = \$$src[$i];
        &$code
            ? push @ret, splice @$src, $i, 1
            : $i++
    }
    @ret
}

my @a = (1, 7, 6, 3, 8, 4);
my @b = grep_filter {$_ > 5} @a;

say "@a"; # 1 3 4
say "@b"; # 7 6 8
like image 22
Eric Strom Avatar answered Oct 01 '22 09:10

Eric Strom