4

要素にコンマを追加し、最後の要素の前に「and」を追加するサブルーチンを作成したいと考えています。たとえば、「12345」が「1、2、3、4、および 5」になるようにします。コンマを追加する方法は知っていますが、問題は結果が「1、2、3、4、および 5」であり、最後のコンマを削除する方法がわかりません。

sub commas {
  my @with_commas;
  foreach (@_) {
    push (@with_commas, ($_, ", ")); #up to here it's fine
    }
    splice @with_commas, -2, 1, ("and ", $_[-1]);
    @with_commas;
  }

おそらくおわかりのように、コンマが追加されているため、新しい配列 (@with_commas) の最後の要素を削除し、古い配列の最後の要素 (@_、サブルーチンに渡される) を追加しようとしています。コンマを追加せずにメインプログラムから)。

これを実行すると、結果はたとえば「1、2、3、4、および 5」になり、最後にコンマが付きます。そのコンマはどこから来ているのですか?@with_commas だけがカンマを取得するはずでした。

どんな助けでも大歓迎です。

4

7 に答える 7

7
sub format_list {
   return "" if !@_;
   my $last = pop(@_);
   return $last if !@_;
   return join(', ', @_) . " and " . $last;
}

print format_list(@list), "\n";

これは、他のほとんどの回答とは異なり、要素が1つだけのリストも処理します。

于 2012-08-30T16:40:42.063 に答える
3

これには CPAN モジュールLingua::Conjunctionがあります。私はそれを自分で使用しており、独自のソリューションを展開するよりも推奨しています。使用構文は非常に単純です。

conjunction(@list);
于 2012-08-30T20:43:21.467 に答える
3

最後の要素を使用joinおよび変更して、次を含めることができますand

my @list = 1 .. 5;
$list[-1] = "and $list[-1]" if $#list;
print join ', ', @list;
于 2012-08-30T16:39:08.200 に答える
2
#!/usr/bin/perl

use warnings;
use strict;

sub commas {
  return ""    if @_ == 0;
  return $_[0] if @_ == 1;
  my $last = pop @_; 
  my $rest = join (", ", @_);
  return $rest.", and ".$last;
}

my @a = (1,2,3,4,5);
print commas(@a), "\n";
于 2012-08-30T16:35:43.107 に答える
1

TIMTOWTDIの精神で(ただし、率直に言って、読みやすさに関しては@perrealの回答の方が優れています):

sub commas {
    my $last_index = $#_;
    my @with_commas = map { (($_==$last_index) ? "and " : "") . $_[$_] }
                          0 .. $last_index;
    print join("," @with_commas)
}

これは Alan の回答 (より複雑/複雑) に多少似ていますが、それと比較した場合の利点は、最後の要素以外の要素に「and」を追加する必要がある場合に機能することです。アランは、正確なオフセット(最後の要素など)がわかっている場合にのみ機能します

于 2012-08-30T16:48:01.220 に答える
1

カンマを追加してから、「および」を追加します。

use v5.10;

my $string = join ', ', 1 .. 5;

substr 
    $string, 
    rindex( $string, ', ' ) + 2,
    0,
    'and '
    ;

say $string;

したがって、2 つ以上の要素がある場合のように作業します。

use v5.10;

my @array = 1..5;
my $string = do {
    if( @array == 1 ) {
        @array[0];
        }
    elsif( @array == 2 ) {
        join ' and ', @array
        }
    elsif( @array > 2 ) {   
        my $string = join ', ', @array;

        my $commas = $string =~ tr/,//;

        substr 
            $string, 
            rindex( $string, ', ' ) + 2,
            0,
            'and '
            ;

        $string;
        }
    };      

say $string;
于 2012-08-30T16:36:08.357 に答える
0

小さなヒント

for( 1 .. 10 ) {
     print ;
     $_ == 10 ? print '' : ($_ != 9 ? print ', ' : print ' and ');
}
于 2013-06-12T16:04:47.190 に答える