Perlのすべてがここにある!

Perl 配列~基本から応用までの逆引き辞典~

カヌレ子

開発エンジニア/Java/Perl/ボールド歴2年

Perlの配列は、他の言語よりも柔軟で使いやすく、初心者にも理解しやすい設計になっています。さらに多くの演算子を使いこなすことで、よりスマートなコーディングが実現できます。

Perlの配列の作法から、目的に応じた演算子の使い方まで1つずつ確認していきましょう。


1.配列とは

配列は、1つの値を格納していた変数と違い、複数の値を格納することができます。使い方は他の言語とあまり変わりません。

C言語のように宣言時に要素数を指定する必要がなく、必要に応じて自動的にサイズが拡張されるので便利です。

Perlの配列は下記の通り、「@」をつけます。これは空のリストで初期化している例です。

@array = ();

宣言時に値を代入する場合は、下記の通りです。数値の場合は「’’」で括る必要はありません。

@array = ('red', 'blue', 'green');

2.基本的な使い方

2-1.配列の1要素のみ取り出したい

配列の1要素を指定する場合は「@」ではなく「$」と添え字を使います。

Perlの添え字は多くの言語と同様0から始まります。

my @array = ('red', 'blue', 'green');
my $color = $array[0];

print “\$color=[$color]\n”;
print "\$array[0]=[$array[0]], \$array[1]=[$array[1]], \$array[2]=[$array[2]]\n";

実行結果:

$color=[red]
$array[0]=[red], $array[1]=[blue], $array[2]=[green]

2-2.配列の内容を全て出力したい

1つの要素を指定する場合は「$」でしたが、全て出力したい場合は「@」です。

print "\@array=[@array]\n";

実行結果:

@array=[red blue green]

2-3.リスト作成が面倒くさい1(qwショートカット)

配列にセットする要素が多い場合は、qwショートカットを使うと便利です。

qw()の他、qw//もよく見ますね。 !! ## {} [] <>でも構いません。

my @array = qw(yellow pink purple orange);
print "\@array=[@array]\n";

実行結果:

@array=[yellow pink purple orange]

2-4.リスト作成が面倒くさい2(範囲演算子)

例えば(’10’, ‘11’, ’12’, ’13’, ’14’, ‘15’)といった、順に1ずつ大きくなるリストを代入するときにこの範囲演算子「..」が使えます。

my @array = (10 .. 15);

for(my $i=0; $i < @array; $i++) {
print "\$array[$i]=[$array[$i]] ";
}
print "\n";

実行結果:

$array[0]=[10] $array[1]=[11] $array[2]=[12] $array[3]=[13] $array[4]=[14] $array[5]=[15]

2-5.配列の要素数を知りたい

要素数は、配列をスカラー変数に代入することで取得可能です。

my @array = ('red', 'blue', 'green');
my $length = @array;

print "\$length=[$length]\n";

実行結果:

$length=[3]

2-6.配列の最後の要素を指定したい

最後の要素は「$#配列名」で指定できます。「-1」としても同じです。

my @array = qw(yellow pink purple orange);

print "\$array[$#array]=[$array[$#array]]\n";
print "\$array[-1]=[$array[-1]]\n";

実行結果:

$array[3]=[orange]
$array[-1]=[orange]

2-7.デフォルトのスペース以外で配列を区切って表示したい

上記までの例の通り、半角スペースで配列の要素が表示されるのがデフォルトです。

変更したい場合は「$”」に任意の区切り記号を設定します。

@array = ('red', 'blue', 'green');

print "\@array=[@array]\n";
$" = ', ';
print "\@array=[@array]\n";

実行結果:

@array=[red blue green]
@array=[red, blue, green]

3.応用的な使い方

3-1.配列を結合・連結したい

(@配列, @配列…)で、複数の配列を一つに連結できます。

my @name1 = ('Ito', 'Kuroda', 'Yamagata', 'Matsukata');
my @name2 = ('Okuma', 'Katsura', 'Saionji', 'Yamamoto');
my @names = (@name1, @name2);

print "\@name1=[@name1], \@name2=[@name2]\n";
print "\@names=[@names]\n";

実行結果:

@name1=[Ito Kuroda Yamagata Matsukata], @name2=[Okuma Katsura Saionji Yamamoto]
@names=[Ito Kuroda Yamagata Matsukata Okuma Katsura Saionji Yamamoto]

3-2.配列の重複した要素を削除したい

重複の内容に配列の要素を整理したい場合は、ハッシュとgrepを使うと簡単です。

他にも実現できる方法はたくさんあります。思いついた方法があれば試してみましょう。

my @numbers = qw(1 2 3 2 2 4 5 4 2 6 7 6 6 4);
print "\@numbers=[@numbers]\n";

my %count;
# 2回以降登場した値は偽となり、grepの対象とならない
@numbers = grep {!$count{$_}++} @numbers; 
print "\@numbers=[@numbers]\n";

実行結果:

重複削除@numbers=[1 2 3 2 2 4 5 4 2 6 7 6 6 4]
@numbers=[1 2 3 4 5 6 7]

3-3.配列を文字列にしたい(join

配列の要素を、1つの文字列にしたい場合はjoinを使います。

下記の「:」で各要素を連結した例です。joinの後に指定している「:」を変更することで、他の区切りで連結できます。

my @array = qw(1 1 2 3 5 8 13);
print "\@array=[@array]\n";
my $str = join (':', @array);
print "\$str=[$str]\n";

実行結果:

@array=[1 1 2 3 5 8 13]
$str=[1:1:2:3:5:8:13]

3-4.文字列を配列にしたい(split)

joinの反対です。上記で文字列にした$strを、また配列に戻してみましょう。

my @new_array = split(/:/, $str);
print "\@new_array=[@new_array]\n";

実行結果:

@new_array=[1 1 2 3 5 8 13]

3-5.配列の後ろに要素を追加したい / 削除したい(push / pop)

後ろに要素を追加したい場合は「push」、取り出したい場合は「pop」を使います。

下記の列ではpushで2駅追加され、popで最後の1駅が取り出されていますね。

my @yamanote = ('shinjuku', 'yoyogi', 'harajuku', 'shibuya');
print "\@yamanote=[@yamanote]\n";

push (@yamanote, 'ebisu', 'meguro');
print "\@yamanote=[@yamanote]\n";

pop (@yamanote);
print "\@yamanote=[@yamanote]\n";

実行結果:

@yamanote=[shinjuku yoyogi harajuku shibuya]
@yamanote=[shinjuku yoyogi harajuku shibuya ebisu meguro]
@yamanote=[shinjuku yoyogi harajuku shibuya ebisu]

3-6.配列の最初に要素を追加したい / 削除したい(unshift / shift)

配列の後ろではなく、先頭に要素を追加したい場合は「unshift」、削除したい場合は「shift」を使います。

unshift (@yamanote, 'shin-okubo');
print "\@yamanote=[@yamanote]\n";

shift (@yamanote);
print "\@yamanote=[@yamanote]\n";

実行結果:

@yamanote=[shin-okubo shinjuku yoyogi harajuku shibuya ebisu]
@yamanote=[shinjuku yoyogi harajuku shibuya ebisu]

unshiftによって先頭に1駅追加され、shiftによって1駅削除されました。

3-7.配列の指定した場所に要素を追加したい / 削除したい(splice)

配列の最初/最後ではなく、途中に追加したり削除したりしたいんだ!という場合はspliceを使います。上記で紹介した「push / pop / unshift / shift」も全てspliceで実現できます。

splice (@yamanote, 1, 1);                    # 先ほどの@yamanoteの1番目から1要素を取り出す
print "\@yamanote=[@yamanote]\n";
splice (@yamanote, 1, 0, 'yoyogi');       # 1番目から0要素を取り出して、’yoyogi’を追加する
print "\@yamanote=[@yamanote]\n";

実行結果:

@yamanote=[shinjuku harajuku shibuya ebisu]
@yamanote=[shinjuku yoyogi harajuku shibuya ebisu]

もし先頭を指定したい場合は、「0番目から」となるので“splice (@yamanote, 0, 1);”となるので注意。

3-8.配列の順番を逆にしたい(reverse)

reverseを使うと簡単に配列の順番を逆にしてくれます。

reverseの結果を新しい配列に代入しているので、@yamanoteの順番は何も変わっていないことが分かります。

my @reverse = reverse(@yamanote);
print "\@yamanote=[@yamanote]\n";
print "\@reverse=[@reverse]\n";

実行結果:

@yamanote=[shinjuku yoyogi harajuku shibuya ebisu]
@reverse=[ebisu shibuya harajuku yoyogi shinjuku]

3-9.配列を昇順 / 降順にソートしたい(sort)

sortは文字列のソートをするか、数値のソートをするかで結果が変わってしまいますので、どちらのソートなのか間違わないように注意しましょう。

①文字列のソート

my @sort = sort (@yamanote);               # 昇順 「sort {$a cmp $b}」と同様
print "\@yamanote=[@yamanote]\n";
print "\@sort=[@sort]\n";
@sort = sort {$b cmp $a} @yamanote;   # 降順 文字コードの大きい順になる
print "\@sort=[@sort]\n";

実行結果:

@yamanote=[shinjuku yoyogi harajuku shibuya ebisu]   ←ソート前
@sort=[ebisu harajuku shibuya shinjuku yoyogi]        ←昇順
@sort=[yoyogi shinjuku shibuya harajuku ebisu]        ←降順

②数値のソート

数値で判断して、小さい順に並べ替えたい場合は、sortの後に「{$a <=> $b}」を指定します。数値しかない配列だからといって、自動で数値としてソートしてくれるわけではないのですね。

my @numbers = (1, 10, 100, 1000, 2, 3.5, -6, -11);
print "\@numbers=[@numbers]\n";
@numbers = sort (@numbers);                     # 文字列の昇順ソートになってしまう
print "\@numbers=[@numbers]\n";
@numbers = sort {$a <=> $b} @numbers;   # ソート 昇順
print "\@numbers=[@numbers]\n";
@numbers = sort {$b <=> $a} @numbers;   # ソート 降順
print "\@numbers=[@numbers]\n";

実行結果:

@numbers=[1 10 100 1000 2 3.5 -6 -11]     ←ソート前
@numbers=[-11 -6 1 10 100 1000 2 3.5]     ←文字列として昇順ソートされた
@numbers=[-11 -6 1 2 3.5 10 100 1000]     ←数値の昇順ソート
@numbers=[1000 100 10 3.5 2 1 -6 -11]     ←数値の降順ソート

3-10.配列から条件に合う要素のみを取り出したい(grep)

grepの後に正規表現などで探したい要素の条件を指定することができます。

my @yamanote = qw/shinjuku yoyogi harajuku shibuya ebisu/;

my @matched1 = grep {/^[a-z]{6}$/} @yamanote; # 英字6文字の要素のみ取り出す
print "\@matched1=[@matched1]\n";

my @matched2 = grep {/shi/} @yamanote;             # “shi”を含む要素のみ取り出す
print "\@matched2=[@matched2]\n";

実行結果:

@matched1=[yoyogi]
@matched2=[shinjuku shibuya]

3-11.配列の全ての要素を変換したい(map)

配列に格納したまま要素を編集したい場合はmapを使います。

foreachでも実現できますが、こちらのほうがよりスマートなコードになっています。

my @numbers = (1000, 100, 10, 3.5, 2, 1, -6, -11);

my @mapped = map {$_ * 2} @numbers;      # 要素を倍の数にする
print "\@numbers=[@numbers], \@mapped=[@mapped]\n";

実行結果:

@numbers=[1000 100 10 3.5 2 1 -6 -11], @mapped=[2000 200 20 7 4 2 -12 -22]

3-12.配列をリファレンスとして扱いたい

#Aの「\@配列名」のように、@の前に\をつけることで配列のリファレンスができます。

#Bで“$yamanote_ref”を出力すると、”@yamanote”の配列を指すアドレスが表示されていることが分かります。C言語でいうポインタのようなものですね。

リファレンスを配列として扱う場合、#Cのように「@$リファレンス名」とします。

リファレンスは配列と違い、#Dのように「$リファレンス名->[添え字]」と記述して要素を取り出します。

my @yamanote = qw/shinjuku yoyogi harajuku shibuya ebisu/;

my $yamanote_ref = \@yamanote;                                  # A
print "\$yamanote_ref=[$yamanote_ref]\n";                    # B
print "\@\$yamanote_ref=[@$yamanote_ref]\n";             # C
print "\$yamanote_ref->[0]=[$yamanote_ref->[0]]\n";     # D

実行結果:

$yamanote_ref=[ARRAY(0x290fe1c)]
@$yamanote_ref=[shinjuku yoyogi harajuku shibuya ebisu]
$yamanote_ref->[0]=[shinjuku]

3-13.多次元配列を作りたい

Perlでは、多次元配列を作るためにリファレンスを使います。

my @new_employees = (
    ['A', '東京都', 22],
    ['B', '埼玉県', 22],
    ['C', '千葉県', 24]
);
print "\$new_employees[0][0]=$new_employees[0][0]\n";           # 1要素を指定
print "\@{\$new_employees[1]}=[@{$new_employees[1]}]\n";   # 2番目の配列を指定

# 一つずつ出力する
foreach my $record (@new_employees) {
	foreach (@{$record}) {
        print "$_\n";
	}
}

実行結果:

$new_employees[0][0]=A
@{$new_employees[1]}=[B 埼玉県 22]
A
東京都
22
B
埼玉県
22
C
千葉県
24

一次元配列と同じように、配列を追加したり削除したりすることもできます。

push (@new_employees, ['D', '沖縄県', 20]);
print "\@{\$new_employees[-1]=[@{$new_employees[-1]}]\n";

実行結果:

@{$new_employees[-1]=[D 沖縄県 20]

4.さいごに

配列を扱う演算子について簡単に紹介しましたが、各演算子にはまだいろいろな使い方があります。

配列は頻繁に使いこないして、効率の良いスマートな実装を目指しましょう。

私たちは、全てのエンジニアに市場価値を高め自身の望む理想のキャリアを歩んでいただきたいと考えています。もし、今あなたが転職を検討しているのであればこちらの記事をご一読ください。理想のキャリアを実現するためのヒントが見つかるはずです。

『技術力』と『人間力』を高め市場価値の高いエンジニアを目指しませんか?

私たちは「技術力」だけでなく「人間力」の向上をもって遙かに高い水準の成果を出し、関わる全ての人々に感動を与え続ける集団でありたいと考えています。

高い水準で仕事を進めていただくためにも、弊社では次のような環境を用意しています。

  • 定年までIT業界で働くためのスキル(技術力、人間力)が身につく支援
  • 「給与が上がらない」を解消する6ヶ月に1度の明確な人事評価制度
  • 平均残業時間17時間!毎週の稼動確認を徹底しているから実現できる働きやすい環境

現在、株式会社ボールドでは「キャリア採用」のエントリーを受付中です。

まずは以下のボタンより弊社の紹介をご覧いただき、あなたの望むキャリアビジョンをエントリーフォームより詳しくお聞かせください。

コメント

文系IT未経験歓迎!【23卒対象】新卒採用のエントリーを受付中!
文系IT未経験歓迎!
【23卒対象】新卒採用のエントリーを受付中!