2017-11-03 11 views
3

「ソース」とは無関係にarrayにプッシュされたhashを作成する方法hashPerl 6でハッシュの配列を作るには?

my %country; 
my Hash @array; 

%country{ 'country' } = 'France'; 
@array.push(%country); 
%country{ 'country' } = 'Germany'; 
@array.push(%country); 

.say for @array; 

出力は次のようになります。

{country => Germany} 
{country => Germany} 

そして、もちろん、それは私が欲しいものではありません。

答えて

2

ときハッシュ%countryを、参照を%countryにプッシュしている配列にプッシュします。このようにして、各配列要素は同じ元のハッシュ%countryを参照します。また、ハッシュの値を変更すると、すべての配列要素に(このすべてが同じハッシュを参照するため)この変更が反映されます。新しいハッシュを押すたびに新しいハッシュを作成したい場合は、代わりに匿名のハッシュを押してみてください。例えば、このように

%country{ 'country' } = 'France'; 
@array.push({%country}); 
%country{ 'country' } = 'Germany'; 
@array.push({%country}); 

%countryのコピーへの参照は、(%countryへの参照の代わりに)毎に押し込まれます。

出力

{country => France} 
{country => Germany} 
+0

ありがとう!私はこの問題をローカライズするのに多くの時間を費やし、現在は '{'と '}'を挿入した後、プログラム全体が期待どおりに動作します。 :)私の質問は、なぜハッシュを押しているときに問題が起こるのですが、スカラー変数を押すときには起こりません。 'my $ x = 1; 私の@values; @ values.push($ x); $ x = 2; @valuesの場合は となります。 #1' –

+1

@EugeneBarskyスカラーは値でプッシュされますが、ハッシュは参照によってプッシュされると思います。だから違いがあります:) –

+1

また、[ルーチンプッシュのドキュメント](https://docs.perl6.org/routine/push)によると、* "pushは引数リストを平坦化しようとしません。または押しつけるものとしてリストすると、それは1つの追加要素になります」* –

2

ほとんどすべてのプログラミング言語にこの問題があります。あなたは同じハッシュを複数回配列に押し込んでいます。ハッシュを変更すると、配列内の両方の参照が変更されます。

あなたがアレイ上に異なるハッシュをプッシュする場合は、あなたが期待する結果表示されます:

my %a = (country => 'China'); 
my %b = (country => 'USA'); 
my Hash @array; 
@array.push(%a); 
@array.push(%b); 
say @array.perl; 

あなたの代わりに2つのハッシュを宣言する、アレイ上にそれを押すと、あなたも、ハッシュをコピーすることができます。これはまたこの問題を解決します:

my %country; 
my @array; 
%country<country> = 'México'; 
@array.push(%country.list.hash); 
%country<country> = 'Canada'; 
@array.push(%country.list.hash); 
say @array.perl; 

ところで、ハッシュをコピーする方法はたくさんあります。キーは、キー/値を取得し、それをハッシュに戻すことです。どのハッシュコンストラクタ、どの平坦化メソッドを使用するかはあなた次第です。 (.kv.list.pairs.flatが何らかの形で、順次要素を取得するすべてのHashメソッドです。ホーコンが示した方法は、その後一人で構文で別のハッシュを作成する要素を取得し、より暗黙的である。)

+0

ありがとうございます!なぜスカラー変数を押してもこれは起こりませんか?どのような変数の型でこれが問題になるかを事前に知る方法? –

+1

@EugeneBarskyほとんどの単一の値は不変(Int/Str/DateTime)なので、実際に何をしているのかを変更するときは、既存の値を変更するのではなく、新しい値を入れます。 –

+0

@BradGilbertしたがって、変数のすべての可変型に対して問題が発生しますか?一般的な解決策はありますか? –

1

あなただけの簡単なキーと値のペア(ないマルチパートハッシュ)ペアを検討したい場合は?

my Pair @array; 
@array.push((:country<Germany>)); 
@array.push((country => "France")); 
say @array; 
say .kv for @array 
+0

アイデアありがとう!一般に、私は多くのkvペアを持つハッシュを使用しなければなりません。 –

関連する問題