Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I filter an array without using a loop in Perl?

Tags:

arrays

perl

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).

like image 291
Lazer Avatar asked Oct 18 '10 14:10

Lazer


People also ask

How do I filter an array in Perl?

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).

How do you filter data from an 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.


2 Answers

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"; 
like image 170
Ruel Avatar answered Oct 06 '22 16:10

Ruel


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.

like image 31
Greg Bacon Avatar answered Oct 06 '22 17:10

Greg Bacon