snakespan
snakespan

Reputation: 1211

Perl Empty Strings inside Arrays

I want to loop over an array of strings, but sometimes if the string is empty, it still gets added as an item.

my $forename = $service->getValue('forename');
my $surname = $service->getValue('surname');

my @selectedNames = ( $forename, $surname );

foreach my $name (@selectedNames) {
    # do something

    if ($trackedName) {
         # log the name
    } else {
         # log a FATAL
    }
}

If the string is empty for $surname, then it shouldn't loop the second time at all, but it always does. How do I prevent this?

Upvotes: 0

Views: 148

Answers (2)

Silvar
Silvar

Reputation: 705

Concerning Frank Förster's response (I don't have enough reputation to reply directly):

Wouldn't grepping using $_ also strip any numeric item with the value 0, and the string "0"? I realize you're not likely to get them as "surnames", but not being prepared for such an eventuality may lead to bugs that are hard to track.


Edit: Here's my solution (after prompting by PerlDuck):

my $forename = $service->getValue('forename');
my $surname = $service->getValue('surname');

my @selectedNames = ( $forename, $surname );

foreach my $name (@selectedNames) {
    next  if (not defined $name  or  $name eq '');

    # do something

    if ($trackedName) {
        # log the name
    } else {
        # log a FATAL
    }
}

Alternately you can just use the original code, but substitute

foreach my $name (@selectedNames)

with

foreach my $name (grep { defined and $_ ne '' } @selectedNames)

If you're worried your "empty" names may include stuff with just whitespace in them, you can use $name =~ /^\s*$/ instead of $name eq ''.

Upvotes: 1

Frank Förster
Frank Förster

Reputation: 371

Just use next unless ($name); as first line of your loop.

Perl handles the values undef and empty string ('') as false and will therefore enter the next loop.

my $forename = $service->getValue('forename');
my $surname = $service->getValue('surname');

my @selectedNames = ( $forename, $surname );

foreach my $name (@selectedNames) {
    next unless ($name);

    # do something

    if ($trackedName) {
         # log the name
    } else {
         # log a FATAL
    }
}

If you want to use grep to filter the list actually you neither need length nor defined: grep { $_ } (@selectedNames) would be enough. Therefore your code would look like

my $forename = $service->getValue('forename');
my $surname = $service->getValue('surname');

my @selectedNames = ( $forename, $surname );

foreach my $name (grep { $_ } @selectedNames) {
    # do something

    if ($trackedName) {
         # log the name
    } else {
         # log a FATAL
    }
}

Upvotes: 0

Related Questions