
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
関数型プログラムになれてれば
読めるコードですけど,Perl風味が混じってるので
ちょっとしんどいですね.
リファレンスを知ってるかどうかが重要です.
{map{$_,1}@array2 }-> {$_}
ここが何をしてるのかわかれば,大体OKかな
map{$_,1}@array2
の部分では,@array2の要素を一個じつ$_1にいれて
1とペアにしています.たとえば,@array2=(a,b,c,d)だったら
aを$_にして,a,1 をつくって
bを$_にして,b,1をつくって・・・とやって
(a,1,b1,c,1,d,1)
というリストを作ります.これがmapの機能
これを { } で囲んで
{ (a,1,b1,c,1,d,1) }
というのを作るんだけども,これは
{ a,1,b1,c,1,d,1 }
と同じで,無名のハッシュ(ハッシュのリファレンス)を
作る.つまり
{a=>1, b=>1, c=>1, d=>1}
と同じ.
リストをそのままハッシュに変換できるということと,それを
無名ハッシュのコンストラクタで処理してるところが
かなりPerl風味です.
このハッシュリファレンスに対して
>{map{$_,1}@array2 }-> {$_}
とするんだけども,後ろの$_はgrepが渡してくる
@array1の各要素ですので
@array1=(a,b,d,x)だとすると
a に対しては 1
b に対しては 1
d に対しては 1
x に対しては undef
となります.
これを ! で否定するのだから
a に対しては false
b に対しては false
d に対しては false
x に対しては true
がでてきて
grepではtrueになるものだけがでてくるので
結果として
@deff=(x)となります.
例では,
@array1=(a,b,d,x)
@array2=(a,b,c,d)
なので,これは,
@array1の中にあって
@array2の中にはない要素を引っ張り出す
というのが正しい言い方であって
一概に「配列を比較する」といいきれるかは微妙です.
そもそも「配列を比較する」ということ自体が
どういう意味かが明確ではないということにも注意が必要です.
No.2
- 回答日時:
> "@deff = grep { !{map{$_,1}@array2 }-> {$_}}@array1;"で比較ができると書かれていました。
もちろんこういうやり方もアリなのですが、初心者の場合後から見た場合に意味が分かる事が重要だと思うので(理解するまでに結構時間がかかった...)次のようなサブルーチンを書いてみました。
サブルーチンにするとどうしても渡された値が正しいかチェックしなければならないため冗長なコードになりますが...
sub eq_array (&;$$) {
my ($pred, $array1, $array2);
if (ref $_[0] eq 'CODE') {
# もしも最初が{ ... }だった場合
($pred, $array1, $array2) = @_;
} else {
# 普通に配列のリファレンス二つが渡された場合
($array1, $array2) = @_;
}
# 配列の数が同じかチェック
if (@$array1 != @$array2) {
return 0;
}
for (my $i = 0; $i < @$array2; $i++) {
if (defined $pred) {
# 最初が{ ... }だった場合
local ($a, $b) = ($array1->[$i], $array2->[$i]);
if (! $pred->()) {
return 0;
}
} else {
# デフォルトは文字で比較 (sortと同じ)
if ($array1->[$i] ne $array2->[$i]) {
return 0;
}
}
}
# 最後まで一緒だったら真
return 1;
}
このサブルーチンはsort演算子に動きを合わせてあります。
使い方は文字で比較する場合、
eq_array \@array1, \@array2
と配列のリファレンスを渡してください。
それぞれの要素について
$a eq $b
で比較されます。
数値で比較する場合はsort演算子のように
eq_array { $a == $b } \@array1, \@array2
としてください。
それぞれの要素について
$a == $b
のように比較されます。
以下このサブルーチンのテストをした時のコードです。
my @array1 = my @array2 = 1 .. 100;
printf "equal?:%d\n", eq_array_str(\@array1, \@array2);
printf "equal?:%d\n", eq_array_num(\@array1, \@array2);
printf "equal?:%d\n", eq_array \@array1, \@array2;
printf "equal?:%d\n", eq_array { $a == $b } \@array1, \@array2;
@array1 = "a" .. "z";
@array2 = reverse @array1;
# use warningsをしていると
# 数値に変換できない文字列を
# ==で比較すると警告を出してくるので
# ここでは数値では比較しない
printf "equal?:%d\n", eq_array_str(\@array1, \@array2);
# printf "equal?:%d\n", eq_array_num(\@array1, \@array2);
printf "equal?:%d\n", eq_array \@array1, \@array2;
# printf "equal?:%d\n", eq_array { $a == $b } \@array1, \@array2;
表示結果:
equal?:1
equal?:1
equal?:1
equal?:1
equal?:0
equal?:0
No.1
- 回答日時:
#!/usr/bin/perl
use warnings;
use strict;
my @array1 = qw(111 222 333 444 555);
my @array2 = qw(222 444);
my @diff;
# オリジナル
@diff = ();
@diff = grep {
!{ map { $_, 1 } @array2 }->{$_}
} @array1;
print "---\n";
print $_, " " foreach @diff;
print "\n";
# map { $_, 1 } @array2 とほぼ同じ働き
my %hash = ( 222, 1, 444, 1);
# 上記は%hash = ( 222 => 1, 444 => 1); と同じ
@diff = ();
@diff = grep { !$hash{$_} } @array1;
print "\n---\n";
print $_, " " foreach @diff;
print "\n";
# @diff = grep { !$hash{$_} } @array1;とやりたいことは同じ
@diff = ();
@diff = grep { !(defined $hash{$_}) } @array1;
print "\n---\n";
print $_, " " foreach @diff;
print "\n";
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
perlで2つの配列を比較する方...
-
index関数で複数個抜き出す
-
UWSCに制限時間を付けたいです
-
VBのReturnの使い方
-
UWSCの終了の仕方
-
VBAで3秒だけ時間を止めたい
-
画面を強制的に再描画させる方法
-
GIFアニメをループさせたくない
-
システム安定性(ゲイン余裕/...
-
イベントの発生を待つ
-
範囲指定したセルを1つずつ飛...
-
Perl実行時のメモリ不足について
-
「偶数・奇数の和」のフローチ...
-
VBAのautofilter、criteriaの配...
-
alarmの使用について
-
Can't use string ("0") as an ...
-
null 参照の例外が実行時に発生...
-
Escキーを押すと、中断する時と...
-
VBAでの一時停止と再開の方法
-
Do whileでExitせず、ループの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
データベースから取得したデー...
-
データのシャッフルについて
-
print文内でのsplice文と代入に...
-
perlで2つの配列を比較する方...
-
フェッチでデータが上書きされます
-
grep関数を用いた複数行からの抽出
-
投稿した文字がカタカナかどう...
-
配列やハッシュで中身が同じか...
-
forの中にリストを書くとその後...
-
正規表現 perl 連続ヒットの...
-
phpのmysql_fetch_arrayに該当...
-
配列を逆に変更したい!!
-
DBIを使ってのデータの取り出し...
-
繰り返して表示するのではなく1...
-
配列内定義サブルーチン呼び出し
-
CGIで数値を含む文字列から0を...
-
組み合わせを作るアルゴリズム
-
変数名を $_ にしたくない
-
ソート時同じ値がある場合、表...
-
python質問
おすすめ情報