Here I am trying to filter only the elements that do not have a substring world
and store the results back to the same array. What is the correct way to do this in Perl?
$ cat test.pl use strict; use warnings; my @arr = ('hello 1', 'hello 2', 'hello 3', 'world1', 'hello 4', 'world2'); print "@arr\n"; @arr =~ v/world/; print "@arr\n"; $ perl test.pl Applying pattern match (m//) to @array will act on scalar(@array) at test.pl line 7. Applying pattern match (m//) to @array will act on scalar(@array) at test.pl line 7. syntax error at test.pl line 7, near "/;" Execution of test.pl aborted due to compilation errors. $
I want to pass the array as an argument to a subroutine.
I know one way would be to something like this
$ cat test.pl use strict; use warnings; my @arr = ('hello 1', 'hello 2', 'hello 3', 'world1', 'hello 4', 'world2'); my @arrf; print "@arr\n"; foreach(@arr) { unless ($_ =~ /world/i) { push (@arrf, $_); } } print "@arrf\n"; $ perl test.pl hello 1 hello 2 hello 3 world1 hello 4 world2 hello 1 hello 2 hello 3 hello 4 $
I want to know if there is a way to do it without the loop (using some simple filtering).
The Perl grep() function is a filter that runs a regular expression on each element of an array and returns only the elements that evaluate as true. Using regular expressions can be extremely powerful and complex. The grep() functions uses the syntax @List = grep(Expression, @array).
One can use filter() function in JavaScript to filter the object array based on attributes. The filter() function will return a new array containing all the array elements that pass the given condition. If no elements pass the condition it returns an empty array.
That would be grep()
:
#!/usr/bin/perl use strict; use warnings; my @arr = ('hello 1', 'hello 2', 'hello 3', 'world1', 'hello 4', 'world2'); my @narr = ( ); print "@arr\n"; @narr = grep(!/world/, @arr); print "@narr\n";
Use grep
:
sub remove_worlds { grep !/world/, @_ }
For example:
@arrf = remove_worlds @arr;
Using grep
is the most natural fit for your particular problem, but for completeness, you can also do it with map
:
sub remove_worlds { map /world/ ? () : $_, @_ }
It's a bit klunky here, but map
gives you a hook in case you want to process the filtered elements before discarding them.
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