私が必要とするのは、2つの配列がperlで同じかどうかを調べる簡単な方法です。順序は重要ではありませんので、私はこのような何かを探しています:2つの配列に同じ要素がPerlで含まれているかどうかを確認するにはどうすればよいですか?
my @a = (1, 2, 3);
my @b = (2, 3, 1);
my @c = (1, 2, 4);
&identical(@a, @b)
リターン1つの
&identical(@a, @c)
戻り0
ありがとう!
私が必要とするのは、2つの配列がperlで同じかどうかを調べる簡単な方法です。順序は重要ではありませんので、私はこのような何かを探しています:2つの配列に同じ要素がPerlで含まれているかどうかを確認するにはどうすればよいですか?
my @a = (1, 2, 3);
my @b = (2, 3, 1);
my @c = (1, 2, 4);
&identical(@a, @b)
リターン1つの
&identical(@a, @c)
戻り0
ありがとう!
あなたはPerl 5.10
以上を使っている(とそうでない場合は、あなたが本当にアップグレードする必要がある)場合は、smart match operatorを使用することができます。
use strict;
use warnings;
my @a = (1, 2, 3);
my @b = (2, 3, 1);
my @c = (1, 2, 4);
#sort each of them (numerically)
@a = sort { $a <=> $b } @a;
@b = sort { $a <=> $b } @b;
@c = sort { $a <=> $b } @c;
if (@a ~~ @b) {
print "\@a and \@b are the same! (after sorting)\n";
}
else {
print "nope\n";
}
if (@a ~~ @c) {
print "\@a and \@c are the same! (after sorting)\n";
}
else {
print "nope\n";
}
また、独自の機能をロールバックできます。
use strict;
use warnings;
my @a = (1, 2, 3);
my @b = (2, 3, 1);
my @c = (1, 2, 4);
print same_elements(\@a, \@b) . "\n";
print same_elements(\@a, \@c) . "\n";
#arguments are two array references
sub same_elements {
my $array_ref_1 = shift;
my $array_ref_2 = shift;
my @arr1 = @$array_ref_1;
my @arr2 = @$array_ref_2;
#If they are not the same length, we are done.
if(scalar(@arr1) != scalar(@arr2)) {
return 0;
}
#sort them!
@arr1 = sort { $a <=> $b } @arr1;
@arr2 = sort { $a <=> $b } @arr2;
foreach my $i(0 .. $#arr1) {
if ($arr1[$i] != $arr2[$i]) {
return 0;
}
}
return 1;
}
Downvoter:ケアを説明する? –
要素の数をハッシュで集計できます。最初の配列にその要素があるたびにカウントを増加させ、他の要素がそれを持つたびにカウントダウンします(またはその逆)。二つの配列はすべて同じ要素を持っている場合は、ハッシュのすべての値は
sub have_same_elements {
my ($arr1, $arr2) = @_;
my %counts =();
$counts{$_} += 1 foreach (@$arr1);
$counts{$_} -= 1 foreach (@$arr2);
return !(grep { $_ != 0 } values %counts);
}
$a_and_b_same = have_same_elements(\@a, \@b); # will be true
$a_and_c_same = have_same_elements(\@a, \@c); # will be false
0(これはあるいは自分自身の文字列化を行うオブジェクトでは動作しない場合があります、注意してくださいになります。ハッシュキーが参照することはできませんそのため、Perlは参照を使用するときに文字列を文字列に変換します。デフォルトのstringizerは、参照をARRAY(0x12345678)
のように変えます。ただし、同じものでなければ参照を区別できます。これはたぶんあなたが知っている)。
まず、あなたの機能を再考する必要があります。
identical(@a, @b);
2つの配列を関数に渡すのではなく、両方の配列のすべての要素を含む単一の配列を渡します。私はあなたのサブルーチンをprototypeすると言うだろう
identical(\@a, \@b);
、それはです:
identical(1, 2, 3, 2, 3, 1);
をあなたの機能が動作するためには、あなたの配列にreferencesに合格する必要があります:それはあなたが言っているかのようですおそらくあなたにそれが解決するmore problemsを引き起こすつもりです。
注文が重要でない場合は、配列を比較する前に並べ替えます。あなたも、いくつかの注意事項...
sub identical {
my $array_ref_1 = shift;
my $array_fef_2 = shift;
use Digest::SHA qw(sha1_hex);
if (ref($array_ref_1) ne "ARRAY") or (ref($array_ref_2) ne "ARRAY") {
return; #Error, need two array references
}
# Dereference Arrays
my @array_1 = @{$array_ref_1};
my @array_2 = @{$array_ref_2};
# Setup Arrays to be one big scalar
my $scalar_1 = join "\n", sort @array_1;
my $scalar_2 = join "\n", sort @array_2;
my $checksum_1 = sha1_hex $scalar_1;
my $checksum_2 = sha1_hex $scalar_2;
if ($checksum_1 eq $checksum_2) {
return 1;
}
else {
return 0_but_true;
カンニングすることができるかもしれない:私は逆参照を持つことができ
0_but_true
は0を返しますが、同時に真の値を返します。このようにして、if (identical(\@A, \@B)) {
のような機能を実行して、その関数が機能することを確認できます。次に、0または1をテストできます。本当の問題は、あなたがこのようなマルチ並ぶ配列だった場合です:join
私が行った方法を使用して
@a = ("this", "that", "the\nother");
@b = ("this", "that\nthe", "other");
を結果のスカラーが等しくなるように原因となります。
私はあなたが(ちょうど適切な比較サブを渡す)あなたが扱っている入力の種類に少なくとも仮定を行う方法でこのようにそれを書くことができると思います:
ので、同じように動作しuse List::Util;
sub identical {
my @this = @{ +shift };
my @that = @{ +shift };
my $cmp = shift // sub { shift eq shift };
return '' unless @this == @that;
for my $idx (List::Util::shuffle keys @this) {
return '' unless $cmp->($this[$idx], $that[$idx]);
}
return 1;
}
:
0> identical([0..100], [0..100])
$res[0] = 1
1> identical([0..100], ['0.0', 1..100])
$res[1] = ''
2> identical([0..100], ['0.0', 1..100], sub {shift == shift})
$res[2] = 1
3> identical(['0.66666666666', 0..10], [2/3, 0..10], sub {shift == shift})
$res[3] = ''
4> identical(['0.66666666666', 0..10], [2/3, 0..10], sub {shift() - shift() < 1e-5})
$res[4] = 1
# if you need this to be true check out https://stackoverflow.com/a/12127428/13992
5> identical([0..100], [List::Util::shuffle(0..100)])
$res[5] = ''
より良い名前を選ぶことができます。これらの配列は、実際には定義によって同一ではありません(同じ順序で同じ要素を持つことを含みます)。あなたが注文を気にしないなら、その名前はそれを反映するべきです。 – cHao
要素を複数回配列に表示できますか? – Zaid