Perl

Perlのdeleteでひっかかった話

More than 1 year has passed since last update.

先日Perlの配列操作で、うっかりdeleteを使ってしまい、あれ??となりハマったのでかきます。

配列操作

配列の最後に要素の追加

my @number_list = (1,2,3,4);
push(@number_list, 5); 

use Data::Dumper;
warn Dumper @number_list;

結果

$VAR1 = 1;
$VAR2 = 2;
$VAR3 = 3;
$VAR4 = 4;
$VAR5 = 5;

配列の先頭に要素の追加

my @number_list = (1,2,3,4);
unshift(@number_list, 0); 

use Data::Dumper;
warn Dumper @number_list;
}

結果

$VAR1 = 0;
$VAR2 = 1;
$VAR3 = 2;
$VAR4 = 3;
$VAR5 = 4;

配列の最後の要素を取り出す

my @number_list = (1,2,3,4);
my $last_number = pop @number_list;

use Data::Dumper;
warn Dumper @number_list;
print "###############" . "\n";
warn $last_number;

結果

$VAR1 = 1;
$VAR2 = 2;
$VAR3 = 3;
###############
4

配列の先頭の要素を取り出す

my @number_list = (1,2,3,4);
my $first_number = shift @number_list;

use Data::Dumper;
warn Dumper @number_list;
print "###############" . "\n";
print $first_number;

結果

$VAR1 = 2;
$VAR2 = 3;
$VAR3 = 4;
###############
1

指定された配列要素を消す

先頭を消す場合

my @number_list = (0,1,2,3,4);
delete($number_list[0]);

use Data::Dumper;
warn Dumper @number_list;

結果

$VAR1 = undef;
$VAR2 = 1;
$VAR3 = 2;
$VAR4 = 3;
$VAR5 = 4;

消したところにundefが入る

末尾を消す場合

my @number_list = (0,1,2,3,4);
delete($number_list[4]);

use Data::Dumper;
warn Dumper @number_list;

結果

$VAR1 = 0;
$VAR2 = 1;
$VAR3 = 2;
$VAR4 = 3;

消したところにundefが入らない

先頭でも末尾でもないものを消す場合

my @number_list = (0,1,2,3,4);
delete($number_list[3]);

use Data::Dumper;
warn Dumper @number_list;

結果

$VAR1 = 0;
$VAR2 = 1;
$VAR3 = 2;
$VAR4 = undef;
$VAR5 = 4;

消したところにundefが入る

Perlの配列の要素を消すとき

splice関数を使う

my @number_list = (0,1,2,3,4);

# @number_listの3番目のインデックスの要素を1つ消す
splice(@number_list, 3, 1); 

use Data::Dumper;
warn Dumper @number_list;

結果

$VAR1 = 0;
$VAR2 = 1;
$VAR3 = 2;
$VAR4 = 4;

コメントで教えていただいたsplice関数を調べたら、これ一つでpopやらunshift...を一つで操作できる

その他

my @number_list = (0,1,2,3,4);

my @hoge;

foreach my $num ( @number_list ) { 
    if ( $num != 3 ) { 
        push(@hoge, $num);
    }   
}

use Data::Dumper;
warn Dumper @hoge;

or

my @number_list = (0,1,2,3,4);

my @hoge = grep{ $_ != 3 } @number_list;

use Data::Dumper;
warn Dumper @hoge;

こっちの方がPerlっぽい(^O^)/

結果

$VAR1 = 0;
$VAR2 = 1;
$VAR3 = 2;
$VAR4 = 4;

おわり

なんで delete 使ってしまったのか、まったく思い出せなくて、PHPって配列の要素削除するときってdelteだっけ?とか調べたけど、違かったのでおそらく思い込みで書いてしまった。
Perlのdeleteはハッシュ要素を削除してキーと値を削除する、でも今回のように配列の要素の削除でも使えるが、基本的にハッシュでしか使わない方が、得策...