Nhân bản mảng đa chiều


8

Tôi muốn sao chép một mảng nhiều chiều @athành một mảng @b.

Tôi đã tiến hành một cách trực quan nhất và tôi đã đưa ra những điều sau đây:

    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;

và bản in ra là:

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

Điều đó có nghĩa là hai mảng @a và @b bị ràng buộc?

Câu hỏi:

  1. Tại sao mảng @a được liên kết với mảng @b (Mục đích của phương thức nhân bản trong tình huống này là gì? Chúng tôi biết rằng bản sao đó hoạt động như ý định cho mảng một chiều)
  2. Làm thế nào tôi thực sự có thể nhân bản @a thành @b (đa chiều)?
  3. Đó là cách hiệu quả nhất (giới hạn thời gian) để làm điều đó?

Câu trả lời:


10

Những gì bạn có không phải là một mảng nhiều chiều, mà là một mảng của các mảng. Vì clonelà nông, nó sẽ chỉ sao chép mảng cấp cao nhất. Trong trường hợp này, clonecũng là dự phòng, vì gán vào một mảng đã là một hoạt động sao chép.

Một sửa chữa đơn giản là sao chép từng mảng lồng nhau:

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

Ngoài ra, bạn có thể sử dụng một mảng đa chiều thực sự. Tuyên bố sẽ như thế này:

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

Và sau đó sao chép vào một mảng khác sẽ là:

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

Các bài tập cũng cần cập nhật để sử dụng cú pháp đa chiều:

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

Và cuối cùng, kết quả của việc này:

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

Là như mong muốn:

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

Là lần dọn dẹp cuối cùng, bạn cũng có thể "đổ" một chuỗi 0s vô hạn về mặt khái niệm vào mảng để khởi tạo nó:

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

Điều đó có nghĩa là cấu trúc 3x3 không cần phải được sao chép ở bên phải.


ĐỒNG Ý. Hiểu rồi. Vì vậy, khi tôi cố gắng thay đổi @a [0] [1] thì trong thực tế, tôi thay đổi Scalar @a [0] (là một mảng), trong trường hợp đó là giá trị thứ hai của mảng. Và khi tôi thay đổi @b [1] [0] trong thực tế, tôi thay đổi nội dung vô hướng của @b [1]. Và bởi vì phương thức nhân bản tạo ra một bản sao nông của mảng @a, cả hai mảng @a và @b đều có nội dung giống như 3 Số vô hướng là các mảng. Đó là lý do tại sao tôi nhận được kết quả tương tự khi tôi in ra hai mảng ở cuối! Đúng không?
jakar

2
@ikarpenis @Larry sử dụng vô hướng (chữ thường 's') theo nghĩa wikipediaScalar(chữ hoa 'S') để có nghĩa là tiêu chuẩn được xây dựng trong thùng chứa vô hướng . A Scalarkhông bao giờ là một mảng; nhưng nó có thể chứa (một tham chiếu đến) một Array. Một nhiệm vụ @a[0][1] = ...không thay đổi vô hướng hoặc Scalar @a[0], và cũng không đặt một cái mới Arraytrong Scalarcontainer @a[0]. Nó chỉ thay đổi giá trị được giữ trong lần thứ 2 Scalartrong hiện tại Arrayđược giữ trong Scalarràng buộc hiện có @a[0].
raiph

5

@a@bkhông bị ràng buộc . Chúng chỉ xảy ra để chứa những điều tương tự. Nó clonekhông tái diễn và chỉ nhân bản Mảng ngoài.

Một cách để đạt được những gì bạn muốn là

@b = @a.map: *.clone; 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.