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で質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) 配列操作について 5 2023/04/18 07:27
- BTOパソコン PCの選び方 6 2022/09/11 00:16
- Perl perlで2次元配列をサブルーチンに値渡しで渡す 5 2022/12/17 18:49
- Access(アクセス) Accessテキストボックス内に2つのフィールドの値を比較して大きい方の値を表示させる方法 1 2022/09/09 10:50
- 声優 声真似が全く上達しません。 練習方法を調べても、「ひたすら自分の声と聴き比べる」としか書かれていませ 5 2023/04/18 23:33
- Visual Basic(VBA) 比較して等しくなかったらセルを赤くする 4 2022/07/19 20:11
- Google Maps 同じ住所か比較 3 2023/04/29 19:16
- 日本語 「名詞+的」で「形容動詞」? 9 2023/01/26 18:30
- Perl perlでリテラル値はメモリにどのように格納されているか? 1 2023/01/15 20:45
- PHP 配列の値の更新方法について 1 2022/08/05 09:49
このQ&Aを見た人はこんなQ&Aも見ています
-
性格の違いは生まれた順番で決まる?長男長女・中間子・末っ子・一人っ子の性格の傾向
同じ環境で生まれ育っても、生まれ順で性格は違うものなのだろうか。家庭教育研究家の田宮由美さんに教えてもらった。
-
perlにて2つのファイル比較
Perl
-
Perlで特定行から特定行までを抜き出したい
Perl
-
二次元配列における要素数のはじき出し
Perl
-
-
4
Can't use string (0") as an ARRAY ref の原因について"
Perl
-
5
多次元配列から重複を削除
Perl
-
6
配列やハッシュで中身が同じか簡単に調べることは可能でしょうか?
Perl
-
7
perlで配列の要素が空なのを知るには?
Perl
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
テキストファイルで提出とは?
-
アルファベットに付いて質問し...
-
perlでリテラル値はメモリにど...
-
perlをバージョンアップしたら...
-
Perl の外部モジュールの利用方法
-
Windows10においての『Perl』の...
-
INDIRECT 横に再度抽出したい
-
perl LWPでURLにアクセスした時...
-
openした後、closeしないでプロ...
-
perl 正規表現でエラー
-
P.Cのシングルチューナーとダブ...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
perlプログラミング 空白行削除
-
Perlで時間の計算
-
perlについての質問
-
perlのプログラミング 部分入れ...
-
ペプシコーラとコカ・コーラとD...
-
perlについての質問
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
データベースから取得したデー...
-
perlで2つの配列を比較する方...
-
DBIを使ってのデータの取り出し...
-
python質問
-
perlでファイルの拡張子を除い...
-
アルファベットn文字の組み合わ...
-
grep関数を用いた複数行からの抽出
-
乱数と順列と組み合わせ
-
半角文字の縦書き表示
-
配列やハッシュで中身が同じか...
-
ループ中でのmy宣言と処理速度
-
桁数指定と四捨五入
-
画面を強制的に再描画させる方法
-
VBAで3秒だけ時間を止めたい
-
VBAでの一時停止と再開の方法
-
VBのReturnの使い方
-
どなたかこのプログラミングを...
-
Escキーを押すと、中断する時と...
-
UWSCの終了の仕方
-
エクセルの当番表を作っていま...
おすすめ情報