简体   繁体   中英

Apply substitution to the first item returned by grep

I have this program

sub f {                                                                                                                                                                                                                       
    return ("A/X", "B/X");                                                                                                   
}                                                                                                                            

$x = grep( /X$/, f() ) =~ s/\/X$//r;                                                                                           
print "$x\n";                                                                                                                

($x) = grep( /X$/, f() ) =~ s/\/X$//r;                                                                                         
print "$x\n";                                                                                                                

( ($x) = grep( /X$/, f() ) ) =~ s/\/X$//;                                                                                        
print "$x\n";                                                                                                                

($x) = grep( /X$/, f() );                                                                                                      
$x =~ s/\/X//;                                                                                                               
print "$x\n";

The result is

2
2
A/X
A

The result I want is

A

but only the last attempt produces it.

In my full program, I want to do this with a single line since I have to do it many times. I want to avoid things like $x[0] and f() is a much more complex function

How can I do it?

my ($x) = map { s{/X$}{}r } grep { /X$/ } f();

or

my $x = ( grep { /X$/ } f() )[0] =~ s{/X$}{}r;

or

use List::Util qw( first );

my $x = ( first { /X$/ } f() ) =~ s{/X$}{}r;

The first silently sets $x to undef if f() returns nothing, while the other two set $x to the empty string with a warning in that situation. The second avoids unnecessary work. The third avoids even more.


As an aside, you asked for the equivalent of the following

my ($x) = map { s{/X$}{}r } grep { m{X$} } f();

But I think you want the following:

my ($x) = map { s{/X$}{}r } grep { m{/X$} } f();

Let's avoid that duplication to avoid making the mistake again!

my ($x) = map { my $s=$_; $s =~ s{/X$}{} ? $s : () } f();

or

use File::Basename qw( fileparse );

my ($x) = map { my ($fn, $dir_qn) = fileparse($_); $fn eq 'X' ? $dir_qn : () }  f();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM