TL;DR
use List::Util qw(sample); my @array = (1..100); # 3個ランダムでとりだす my @random_pickup = sample 3, @array;
人間生きていると配列の中身からランダムにn個取得したいときがあります。Perl書いているときもありますね。
よくある方法は次のような感じでしょうか
my @array = (1..100); my @random_array = shuffle @array ; my @random_pickup = splice @random_array, 0, 3;
List::Utilのshuffleを使い配列をランダムにばらしたあとに、標準関数のspliceを使い特定の数の値を取り出してきます。
これだと@random_pickup
には3つのランダムな数が入る訳ですね。
ただしこの方法だと必ず全件をshuffleしないといけないため、巨大な配列を対象にする場合はそこそこコストが掛かります。
他には結局@random_pickup
が必要な場合は、中間変数の@random_array
が不必要ですね。
(最も、工夫すれば中間変数を作らずにかけますが...)
そこでオススメなのがList::Utilのsample関数です。1.54から同梱されているので、比較的最近のList::Utilになら入っています。 ちなみにList::MoreUtilsにも入っています。
書き方は簡単で以下の感じです。
my @items = sample $count, @values; # sample {取得したい数}、 {リスト}
$count
が@values
の配列長より大きい場合は、shuffle
と同じ挙動になります。
近年のList::UtilはXS(C言語実装)も同梱されており、sampleも見てみるとC言語レベルで特定個数のランダム取得をしてくれています。 このため、コスト的にもshuffleしてからspliceなどで取得するより最適化されておりオススメです。 metacpan.org