If operator with multiple conditions in perl

I am trying to construct a if

multi-conditional statement without being too verbose. I currently have:

my $string = "Hamburger";
my @string_as_array = ( $string =~ m/.../g );
my $x=(scalar @string_as_array);
for(my $i=0; $i<$x; $i++)   {
    if ($string_as_array[$i] eq "Ham" || $string_as_array[$i] eq "bur") {
        print "CHEESE";
    }
    elsif ($string_as_array[$i] eq "ger")   {
        print "WICH";
    }
    else {
        print $string_as_array[$i];
    }
}
print "\n";

      

Ideally I would like to do something like this for the first statement if

, if possible:

my $string = "Hamburger";
my @string_as_array = ( $string =~ m/.../g );
my $x=(scalar @string_as_array);
for(my $i=0; $i<$x; $i++)   {
    if ($string_as_array[$i] eq "Ham" || "bur") {
        print "CHEESE";
    }
    elsif ($string_as_array[$i] eq "ger")   {
        print "WICH";
    }
    else {
        print $string_as_array[$i];
    }
}
print "\n";

      

If possible.

+3


source to share


3 answers


my %map = (
   'Ham' => 'CHEESE',
   'bur' => 'CHEESE',
   'ger' => 'WICH',
);

say $string =~ s{(...)}{ $map{$1} // $1 }serg;

      


Other things are much worse in need of simplification!

Soup symbol

my $x=(scalar @string_as_array);
for (my $i=0; $i<$x; $i++) 

      

simplifies

for (my $i=0; $i<@string_as_array; $i++) 

      

which simplifies to

for my $i (0 .. $#string_as_array)

      

But you don't really need the index (elements only), so replace it with

for my $part (@string_as_array)

      



or even

for my $part ( $string =~ /.../sg )

      

This already gives us something cleaner:

for my $part ( $string =~ /.../sg ) {
    if ($part eq "Ham" || $part eq "bur") {
        print "CHEESE";
    }
    elsif ($part eq "ger")   {
        print "WICH";
    }
    else {
        print $part;
    }
}

      

This suggests that we are now asking for a hash lookup.

my %map = (
   'Ham' => 'CHEESE',
   'bur' => 'CHEESE',
   'ger' => 'WICH',
);

for my $part ( $string =~ /.../sg ) {
    print $map{$part} // $part;
}

print("\n");

      

$part

is completely pointless, so you can save memory by switching to a while loop using $1

.

while ( $string =~ /(...)/sg ) {
    print $map{$1} // $1;
}

print("\n");

      

Final conversion:

say $string =~ s{(...)}{ $map{$1} // $1 }serg;

      

+6


source


This is possible with interleaved regular expressions.



if ($string_as_array[$i] =~ /^(?:Ham|bur)$/) {
    ...
}

      

+2


source


||

, &&

, or

And and

- all binary operators, that is, they require two operands. Instead, you can use grep

that takes a list of things and filters them with some predicate expression:

if ( grep { $string_as_array[$i] eq $_ } qw(Ham bur) ) {
   ...
}

      

+1


source







All Articles