配列の差

id:d4-1977:20050924を見て、ワタシも考えてみる。二つの配列から重複しない値を取り出すにはどうするか。

my @diff;
my @temp1 = (1, 2, 3, 4);
my @temp2 = (1, 3, 4);
my %temp;
$temp{$_}++ foreach @temp1, @temp2;
foreach (@temp1, @temp2) {
    push @diff, $_ if $temp{$_} eq 1;
}
print @diff;

パッと思いつくのはこんなコード。一度見た値をハッシュに記憶して、一度しか出てこない値を取り出す処理。ただ、小さな配列なら大した差ではないだろうけど、巨大な配列だとforeachのときに一時的にコピーするときのオーバーヘッドが大きいので、

my @diff;
my @temp1 = (1, 2, 3, 4);
my @temp2 = (1, 3, 4);
my %temp;
$temp{$_}++ foreach @temp1;
$temp{$_}++ foreach @temp2;
foreach (@temp1) {
    push @diff, $_ if $temp{$_} eq 1;
}
foreach (@temp2) {
    push @diff, $_ if $temp{$_} eq 1;
}
print @diff;

みたいに、2回に分けたほうがいいかもしれない。
順番を気にしないなら、keysを使って

my @diff;
my @temp1 = (1, 2, 3, 4);
my @temp2 = (1, 3, 4);
my %temp;
$temp{$_}++ foreach @temp1, @temp2;
foreach (keys %temp) {
    push @diff, $_ if $temp{$_} eq 1;
}
print @diff;

こういうコードもありかな。