Just For Fun

Twitterでネタにするほどでもなく、Facebookで語るほどでもない話題の置き場

Perlで柔軟な配列処理ができるspliceを使ってみる。

perlのコードレビューでsplice関数が使われてて、配列をなんかいじるやつなんだろうけど使ったことないな〜となったので少し調べてみました。

■ 要素を削除(取得)する

とりあえず一番シンプルな使い方。

splice(ARRAY, OFFSET, LENGTH)

mai.pl

use strict;
use warnings;
my @mai = qw/shiraishi shinuchi fukagawa/;

# @maiから3番目の要素一つを削除(取得)する
my @seibo = splice @mai, 2, 1;

print $_ , " mai\n" for (@mai);
print "聖母 ", @seibo , " mai\n";

【出力結果】

> $ perl mai.pl
shiraishi mai
shinuchi mai
聖母 fukagawa mai

■ 要素を追加する

4つ目の引数を使って、好きな追加することが出来ます。
(さらにLENGTHを0にすることで要素を消すことなく!!)

splice(ARRAY, OFFSET, LENGTH, LIST)

saito.pl

use strict;
use warnings;

my @saito = qw/yuri asuka/;

# @saitoの2番から0個要素を削除して"chiharu"を追加
splice @saito, 1, 0, qw/chiharu/;

print "saito ", $_ ,"\n" for (@saito);
> $ perl saito.pl
saito yuri
saito chiharu
saito asuka

■ 配列を配列に追加する

ある配列に対して、配列を途中にぶっこんだり出来ます。

seira.pl

use strict;
use warnings;
my @seira = qw/ikoma hoshino/;

# @seiraの1番目の要素から1個要素を削除して別の配列を追加
splice @seira, 0, 2, qw/nagashima miyazawa hatanaka/;

print $_ ," seira\n" for (@seira);
> $ perl seira.pl
miyazawa seira
hatanaka seira
nagashima seira

すごい、思ってた以上にいろいろできる!

指定したハッシュの要素を消すときにdeleteを良く使いますが、それの配列ver.みたいな認識で使えそうです。

あまりケースは考えられないですが、配列に対して無理やりdeleteを使うことも出来るようです。ただしこれは非推奨のようです。

警告: 配列の値に対して delete を呼び出すことは強く非推奨です。 Perl の配列要素を削除したり存在を調べたりする記法は概念的に一貫しておらず、 驚くべき振る舞いを引き起こすことがあります。

(http://perldoc.jp/func/delete より)

どうなるか実験したいところですが、今日は割愛。

ということで、この関数をうまく使えばpop,push,shift,unshiftといった基本的な配列操作は全部できるだろうことがわかりました。

push(@a,$x,$y)      splice(@a,@a,0,$x,$y)
pop(@a)             splice(@a,-1)
shift(@a)           splice(@a,0,1)
unshift(@a,$x,$y)   splice(@a,0,0,$x,$y)
$a[$i] = $y         splice(@a,$i,1,$y)

(http://perldoc.jp/func/splice より)

Perl & JavaScript - 万能配列操作関数spliceを覚えておこう

古い記事だけどダンさんが紹介していた。


ちなみにコードレビューで読んだspliceの利用パターンは、ざっくり説明すると、ある日時の情報を持ったfrom_paramto_paramのペアが順番にまとめられた@hogeに対して、それぞれのfrom_paramからto_paramまでの期間を用いて処理すると言ったものでした。

# @hogeという配列の0番目から2つずつ要素を取り出して処理を回す
while (my ($from_param, $to_param) = splice @hoge, 0, 2) { ... }