Làm thế nào để tôi lặp qua một mảng bên trong hàm băm Raku?


8

Đây có vẻ là một câu hỏi đơn giản, nhưng Perl6 / Raku không hành xử như tôi mong đợi. Tôi đang cố gắng tạo một tham chiếu đến một mảng trong hàm băm, nhưng không nhận được hành vi mong đợi. Trong Perl5, câu trả lời sẽ liên quan đến việc truy cập mảng bằng cách tham chiếu, nhưng tôi không thấy cú pháp tương đương cho Perl6 / Raku.

my $jsonstr = q:to/END/;
{
    "arr" : [
        "alpha","beta","delta","gamma"
    ]
}
END

my %json = from-json $jsonstr;
my @arr = %json{'arr'};
say "Arr length is " ~ @arr.elems; # Expect 4, get 1
say "Orig length is " ~ %json{'arr'}.elems; # Get expected value of 4
say "Arr[0] is " ~@arr[0].^name ~ " of length " ~ @arr[0].elems; # First index is array

say %json{'arr'}[0]; # Indexing into array in original location works as expected
say @arr[0][0]; # But when assigned, it needs an extra index

my @arr2 = @arr[0]; # Same issue in re-assignment here
say "Arr2[0]: " ~ @arr2[0] ~ ", length of " ~ @arr2.elems;

Làm cách nào để tôi có được một biến @arr mới để tham chiếu mảng lồng mà không có lớp chỉ mục [0] khó hiểu này? Đây có phải là một lỗi không, hay tôi thiếu một cái gì đó trong sự hiểu biết của tôi về xử lý Array / ref của Raku? Cảm ơn.

Câu trả lời:


7

Khi bạn gán giá trị trong khóa arrcho Mảng, @arrnó sẽ lấy giá trị trong %json{'arr'}đó là Đối tượng mảng ["alpha","beta","delta","gamma"]và đặt nó vào @arrđể bạn có được một mảng của Array với 1 mục.

Bạn có một vài lựa chọn:

Bạn có thể liên kết @arrtới %json{"arr"}vớimy @arr := %json{"arr"}

Hoặc bạn có thể chuyển %json{"arr"}danh sách tớimy (@arr) = %json{"arr"}

Bạn phải nhớ trong Raku Array là các Đối tượng.


5
Từ quan điểm hiệu suất, my @arr := %json<arr>giải pháp là tốt nhất, vì nó không cần sao chép bất kỳ giá trị nào, cũng không cần tạo thêm bất kỳ đối tượng nào.
Elizabeth Mattijsen

2

Như thường lệ, sau khi viết + đăng câu hỏi của tôi, tôi đã trả lời câu hỏi của riêng mình.

my @arr = %json{'arr'}.Array;

Tôi không hiểu tại sao điều này là cần thiết, nhưng nó mang lại hành vi mong muốn.


3
%json{'arr'}là một vô hướng (nghĩ, tham chiếu đến một mảng). Gọi phương thức Array là "dereferences" vô hướng, hay chính xác hơn là đưa nội dung vô hướng từ thùng chứa vô hướng của nó vào một thùng chứa danh sách. Bạn cũng có thể đã viết %json{'arr'}.flathoặc |%json{'arr'}, mặc dù tôi nghĩ rằng Arrayphương pháp này nhanh hơn một chút trong trường hợp này.
Holli

1
Để công phu. Trong Raku, Mảng và Danh sách không tự động làm phẳng, do đó my @a = (1,2), (3,4)sẽ tạo ra một mảng các danh sách có hai phần tử, không phải là một mảng các số nguyên có bốn.
Holli

2
Raku không có bất kỳ tài liệu tham khảo nào, nó chỉ có các giá trị và thùng chứa bất biến. Giải pháp của bạn thực hiện như sau: 1. ép buộc Arrayđối tượng trong hàm băm thành một Array: điều này tự nó là một noop, nhưng quan trọng hơn, nó làm mất vùng chứa trong đó Array được lưu trữ trong hàm băm. Vì Arrayđối tượng là Iterable, nó sẽ sao chép các giá trị của nó vào @arrmảng, có khả năng thực hiện nhiều công việc không cần thiết cho các mảng lớn.
Elizabeth Mattijsen
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.