Perl楽しいから好き

Perlをはじめとしたプログラミング周りのあれこれについて。モダーンなPerlを楽しんでいます。

Perlで、とある配列を指定した要素数ごとに別の配列リファレンスに分割する処理をList::MoreUtilsモジュールで書き直してみた

『初めてのPerl 第7版』を練習問題もこなしつつ、自分史上最高なんじゃないかというくらい丁寧に読み進めています。この本、過去の版のものを何度か読んでたんですが、ビット演算子とかプロセス管理とか新しい学びがいっぱい。ホントに適当に読んでたんだなーと反省してます。

で、16章の5項に先日書いたコレ
 ↓

perl48.hatenablog.com


をもっとシンプルに実現できそうなモジュールが紹介されてました。


紹介されてたのは、List::MoreUtilsモジュールのnatatimeというサブルーチンです。早速前回書いたコードを書き換えてみます。

まずはテストから。前回と異なるのは、natatime 使うと分割した時に端数(13個の要素の配列を3つずつに分割したときの残り1個)もちゃんと拾ってくれるところです。ということでテストの期待する結果($expected)部分を書き直しました。

#!/usr/bin/env perl
use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../lib";
use Test::More tests => 2;

BEGIN {use_ok('MyArrayUtility')}

# MyArrayUtility::divide_arrayのテスト
my @arr = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
my $arr_ref = \@arr;
my $item_number_in_list = 4;
my $divided_arr_ref = MyArrayUtility::divide_array($arr_ref, $item_number_in_list);
my $expected = [
    [ 1, 2, 3, 4 ],
    [ 5, 6, 7, 8 ],
    [ 9, 10, 11, 12 ],
    [ 13 ],
];
is_deeply($divided_arr_ref, $expected, 'divide_array');

実処理部分はこんな感じ。
 ↓

package MyArrayUtility;

use strict;
use warnings;
use utf8;
use List::MoreUtils qw/natatime/;

# 配列を指定した要素数ごとに別の配列に分割する処理
sub divide_array {
    my ($arr_ref, $item_number_in_list) = @_;
    my $iterator = natatime $item_number_in_list, @$arr_ref;

    # 結果を格納する配列リファレンス
    my $divided_arr_ref = [];

    while (my @divided = $iterator->()) {
        push(@{$divided_arr_ref}, \@divided);
    }

    return $divided_arr_ref;
}


1;


前よりもスッキリしてイイ感じ。
テスト書いておくと、リファクタリングが楽でイイですねー。