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.
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.
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.
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.
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.
Know your libraries, mang.
use List::MoreUtils qw(part);
part { $_>5 } (1, 7, 6, 3, 8, 4)
returns
(
[1, 3, 4],
[7, 6, 8],
)
my @a = (1, 7, 6, 3, 8, 4);
my (@b, @c);
push @{ $_ > 5 ? \@b : \@c }, $_ for @a;
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With