多次元配列の複製


8

多次元配列@aを配列に複製したい@b

私は最も直感的な方法で進み、次のことを思いつきました:

    my @a = [0, 0, 0], [0, 0, 0], [0, 0, 0];

    my @b = @a.clone;

    @a[0][1] = 1;
    @b[1][0] = 1;

    say '@a : ' ~ @a.gist;
    say '@b : ' ~ @b.gist;

そして、プリントアウトは:

    @a : [[0 1 0] [1 0 0] [0 0 0]]
    @b : [[0 1 0] [1 0 0] [0 0 0]]

つまり、2つの配列@aと@bがバインドされているということですか。

質問:

  1. 配列@aが配列@bにバインドされている理由(この状況でのcloneメソッドの目的は何ですか?クローンは1次元配列に対して意図したとおりに動作することがわかっています)
  2. @aを@bに実際に複製するにはどうすればよいですか(多次元)?
  3. それを行う最も効率的な方法(時間制限付き)はどれですか?

回答:


10

あなたが持っているのは多次元配列ではなく、むしろ配列の配列です。cloneは浅いので、最上位の配列をコピーするだけです。この場合、clone配列への割り当てはすでにコピー操作であるため、も冗長です。

単純な修正は、ネストされた配列のそれぞれを複製することです:

my @b = @a.map(*.clone);

または、実際の多次元配列を使用することもできます。宣言は次のようになります。

my @a[3;3] = [0, 0, 0], [0, 0, 0], [0, 0, 0];

そして、別の配列へのコピーは次のようになります:

my @b[3;3] = @a;

多次元構文を使用するには、割り当ても更新する必要があります。

@a[0;1] = 1;
@b[1;0] = 1;

そして最後に、この結果:

say '@a : ' ~ @a.gist;
say '@b : ' ~ @b.gist;

希望どおりです:

@a : [[0 1 0] [0 0 0] [0 0 0]]
@b : [[0 0 0] [1 0 0] [0 0 0]]

最後のクリーンアップとして、概念的に無限の0sのシーケンスを配列に「注入」して初期化することもできます。

my @a[3;3] Z= 0 xx *;

つまり、3x3構造を右側で複製する必要はありません。


OK。とった。したがって、@ a [0] [1]を変更しようとすると、実際にはスカラー@a [0](配列)を変更します。その場合、配列の2番目の値です。そして、実際に@b [1] [0]を変更すると、@ b [1]のスカラーコンテンツが変更されます。また、cloneメソッドは配列@aの浅いコピーを作成するため、配列@aと@bの両方に、配列である同じ3つのスカラーがコンテンツとして含まれます。そのため、最後に2つの配列を出力しても同じ結果が得られます。あれは正しいですか?
jakar

2
で@Larry使用スカラー(小文字の「s」を)@ikarpenis ウィキペディアの感覚Scalar意味する(大文字の「S」)スカラーに建て楽の標準コンテナを。A Scalarが配列になることはありません。しかし、それ(への参照)を含むことができますArray。割り当て@a[0][1] = ...によってスカラーまたはが変更されることはScalar @a[0]ありません。またArrayScalarコンテナーに新しい値が配置されること@a[0]もありません。それは、2番目Scalarに保持されている値Arrayを、既存のScalarバインド済みに保持されている既存のものに変更するだけ@a[0]です。
ライフ

5

@aそして、@bされていないバインド。それらはたまたま同じものを含んでいるだけです。clone再帰とだけ外側の配列のクローンをしません。

あなたが望むものを達成する1つの方法は

@b = @a.map: *.clone; 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.