4.2. Printing a List with CommasProblemYou'd like to print out a list with an unknown number of elements with an "and" before the last element, and with commas between each element if there are more than two. SolutionUse this function, which returns the formatted string: sub commify_series { (@_ == 0) ? '' : (@_ == 1) ? $_[0] : (@_ == 2) ? join(" and ", @_) : join(", ", @_[0 .. ($#_-1)], "and $_[-1]"); } DiscussionIt often looks odd to print out arrays: @array = ("red", "yellow", "green"); print "I have ", @array, " marbles.\n"; print "I have @array marbles.\n";
What you really want it to say is, Example 4.1 gives a complete demonstration of the function, with one addition: If any element in the list already contains a comma, a semi-colon is used for the separator character instead. Example 4.1: commify_series (continued)#!/usr/bin/perl -w # commify_series - show proper comma insertion in list output @lists = ( [ 'just one thing' ], [ qw(Mutt Jeff) ], [ qw(Peter Paul Mary) ], [ 'To our parents', 'Mother Theresa', 'God' ], [ 'pastrami', 'ham and cheese', 'peanut butter and jelly', 'tuna' ], [ 'recycle tired, old phrases', 'ponder big, happy thoughts' ], [ 'recycle tired, old phrases', 'ponder big, happy thoughts', 'sleep and dream peacefully' ], ); foreach $aref (@lists) { print "The list is: " . commify_series(@$aref) . ".\n"; } sub commify_series { my $sepchar = grep(/,/ => @_) ? ";" : ","; (@_ == 0) ? '' : (@_ == 1) ? $_[0] : (@_ == 2) ? join(" and ", @_) : join("$sepchar ", @_[0 .. ($#_-1)], "and $_[-1]"); } Here's the output from the program:
As you see, we don't follow the ill-advised practice of omitting the final comma from a series under any circumstances. To do so introduces unfortunate ambiguities and unjustifiable exceptions. The examples above would have claimed that we were the offspring of Mother Theresa and God, and would have had us eating sandwiches made of jelly and tuna fish fixed together atop the peanut butter. See Also
Fowler's
Modern English Usage
; we explain the nested list syntax in
Recipe 11.1
; the |
|