[Perl]重複する商品番号に連番をつけたい

Author :

ネットショップ用のデータ生成をしてて出てきたのでメモ。

取引先からもらった商品データのリストがあります。これを、いまからショッピングモールサイトに登録しようとしている、とお考えください。

商品番号にはいくつか重複があり、一部の番号は3個以上あります。ただし、ショップサイトへの登録には、商品番号が重複してはなりません。なので、これを連番つきに変えるというプログラムを書いてみました。

チェック動作をしているのはcheck_overlapというサブルーチンです。

実際に割り振った番号を記録しておく配列と、重複を見つけたときに記録しておくハッシュを用意しておきます。
ひとつずつの商品番号に対してそれまで割り振った番号の中から照合して、重複を見つけたらその商品番号がいままで何回でてきたかをハッシュから読み、ひとつ進めた番号を振る、という動作をしています。


#番号の一覧。いくつか重複しています。
my @data = (
    'aaa',
    'ccc',
    'acacac',
    'aaaccc',
    'bbb',
    'bcbcbc',
    'bbbccc',
    'aaa',
    'ccc',
    'bbb',
    'aaa',
    'ccc',
);
 
 
#重複チェック用の変数を用意しておく
our @item_numbers;
our %overlaps;
my @result; #変更後のリスト
 
 
foreach my $number (@data){
    push (@result, &check_overlap($number) );
}
 
foreach my $number (@result){
    print $number."\n";
}
exit;
 
 
sub check_overlap{
    my $number = shift;
    
    foreach my $dnum (@main::item_numbers){
        if($dnum eq $number){#もし重複があったら
            my $i;
            if($main::overnums{$dnum}){#重複してる番号リストに載ってたら
                $i = $main::overnums{$dnum} + 1;#次の番号を用意しておく
            }else{
                $i = 1;#はじめての場合は1を
            }
            $number .= "_".$i;#連番をつける
            $main::overnums{$dnum} = $i;#つけた連番を記録しておく
            last;
        }
    }
    push (@main::item_numbers, $number);
    
    return $number;
}

出力結果

aaa
ccc
acacac
aaaccc
bbb
bcbcbc
bbbccc
aaa_1
ccc_1
bbb_1
aaa_2
ccc_2