14

There is probably an easy solution to this, but I can't figure it out. I am looking to:

  • take a CSV file into an array
  • loop through the array and split fields into variables
  • if the array field is empty then set the variable to "N/A"

Note: It is only setting the $variable to "N/A" that I cannot get working.

For example:

foreach $var (@list) {

($name,$date,$size, etc...)=split(/,\"/,$var);

}

How would I set $date to "N/A" if the field in the array is empty?

so to produce:

$name = Jim
$date = N/A
$size = small

I hope this makes sense and is easy to fix. -Thanks

2
  • What will be the input like if date is missing? If the input is: somename,200 (where 200 is size), then date would be set as 200 right? Commented Dec 20, 2010 at 13:44
  • /,\"/ smells funny. Do your fields begin with a quote and not end with a quote? Are you stripping a trailing quote from the data after the split call? Does the first field not begin with a quote? Commented Dec 20, 2010 at 19:39

5 Answers 5

24

Assuming the variable $date is undefined when "empty":

if (!defined($date)) {
  $date = 'N/A';
}

Or more concisely:

$date //= 'N/A';

Or if it really is an empty string, i.e. $date = ''; (this will also work in the case where $date is undefined, but you don't want to use this if you only want to identify the case where it is undefined):

if ($date eq '') {
  $date = 'N/A';
}

Or more concisely (note that this will also set $date to N/A if $date is '0' due to Perl's weak typing):

$date ||= 'N/A';
Sign up to request clarification or add additional context in comments.

5 Comments

This is also very helpful to what I was looking for. Thank you for the answer.
You could do also : $date ||= 'N/A';
@Marcog - the "||=" is a bug if the values contain "0". Probably not the case for "date" field but you still should mention that caveat
Just a note, but ||= probably doesn't do what you want if you have zeros in your data. my $test = 0 || 'N/A'; => $test is 'N/A'. Maybe $test = defined($test) ? $test ne '' ? $test : 'N/A' : 'N/A'; If you only care about undefined values and have a 5.10+ Perl, $test //= 'N/A'; will do just fine. EDIT: Boy, am I a slow typist.
@Hugmeir Edited in the //= which I was unaware of. Already noted the 0 bit thanks to @DVK.
6
  1. As far as your third bullet point and the actual question: to check for emptiness:

    • For empty string, you can either do the above-mentioned eq "", or you can check the string length: $var = "N/A" unless length($var);;

    • For an undefined of empty string, in Perl 5.10 you can use the "defined-or" (//) operator to do the short version: $var = "N/A" unless length($var // '');

    • In Perl before 5.10 where "defined-or" is not available, you will either have to spell out the defined check: $var = "N/A" unless defined $var && length($var);

    • ... or, you can just stop caring about undefined warnings by turning them off (h/t brian d foy):

      no warnings 'uninitialized';
      $_ = "N/A" unless length($_) foreach ($name,$date,$size, etc...);
      use warnings 'uninitialized'; # Always turn back on.
      
  2. However, please note that you also should consider a different approach to the first two bullet points. Implementing your own CSV parser which is 100% correct is not trivial - for example, your sample code will break if any of the fields contain a double quote.

    Instead, you should always use one of the standard Perl CSV parsers, such as Text::CSV_XS.

1 Comment

++ for // and Text::CSV. Relevant perldoc link for //: perldoc.perl.org/perlop.html#C-style-Logical-Defined-Or
3
$name = "N/A" if (!defined($name) || ($name eq ""))
$date = "N/A" if (!defined($date) || ($date eq ""))
$size = "N/A" if (!defined($size) || ($size eq ""))

Make sure you are using string comparison for comparing strings :)

5 Comments

Date will still be defined, if input has empty value for date
You should use '' and not "" if no interpolation is expected.
Okay, this is a tad off topic, but why? Besides being in PBP, is there any particular reason to use '' instead of ""? From my two-second experiment, they turn into the same opcodes. For whatever its worth, I use '', because I like how it looks (and I'm not going to use something silly like q{} unless I can help it).
@Hugmeir "" interpolates escaped characters such as \n, \t, \`, etc. while ''` doesn't. 'hello\n will literally be hello\n whereas "hello\n" will be hello<newline>.
I'm asking in the context of empty strings, though.
2

What will be the input like if date is missing? If the input is: somename,200 (where 200 is size), then date would be set as 200 right?

If the input is like this somename,,200

where 200 is size, and because date is unavailable it is set to empty. Then you can do a simple if-check:

if($date eq '')
{
  $date = "NA";
}

Note $date will be defined, it will be just set to empty

1 Comment

This post as well as proxon's post seems to be mainly what I was looking for. I was having problems with it being defined and still outputting an empty value. I just tried implenting this into my code and it helped me to create the desired output.
1
if ($date eq '') { print "STRING IS EMPTY\n" } else { Print "STRING IS NOT EMPTY\n";}

we can use the above code to identify the empty string ,and using the regular expression is more efficient. The "=~" operator and using regular expression also we can also this problem.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.