2017-12-27 106 views
10

Ánh xạ thông thường áp dụng một hàm cho phần tử danh sách và tạo thành phần tử của danh sách kết quả. Ví dụ: nếu danh sách là (1, 2, 3,) và ánh xạ hàm vuông, bạn sẽ nhận được danh sách mới (1, 4, 9,).Cách đơn giản để lập bản đồ nhóm các phần tử danh sách tuần tự

Có cách nào để ánh xạ nhóm các phần tử tuần tự của danh sách không? Ví dụ: nếu danh sách là <8 2 7 2 6 9 4 9 6 1> và tôi muốn tính tổng của mỗi 2 phần tử trong danh sách để tạo <10 9 9 8 15 13 13 15 7>?

Tôi chắc chắn có thể viết thường trình để duyệt qua danh sách. Nhưng tôi đang tìm kiếm một cách dễ dàng hơn, giống như toán tử giảm hoặc giống như việc thu thập/lấy.

Trả lời

11

bạn ca n sử dụng phương pháp .rotor để phân vùng một danh sách vào danh sách con chồng chéo:

say <8 2 7 2 6 9 4 9 6 1>.rotor(2 => -1); 

# Output: 
# ((8 2) (2 7) (7 2) (2 6) (6 9) (9 4) (4 9) (9 6) (6 1)) 

Các 2 => -1 là một đối số Pair mà nghĩa cho phương thức mà nó nên tạo ra các danh sách con bằng cách "hai về phía trước, một trở lại" ở mỗi bước.

Sau đó, bạn chỉ có thể sử dụng .map để áp dụng hoạt động của bạn (ví dụ tổng hợp) cho mỗi sublist:

say <8 2 7 2 6 9 4 9 6 1>.rotor(2 => -1).map(*.sum); 

# Output: 
# (10 9 9 8 15 13 13 15 7) 
+2

Cảm ơn smls !! Điều đó thật tuyệt !! Làm cho tôi yêu perl6 hơn nữa !! – lisprogtor

6

Cách lập trình chức năng để thực hiện việc này là tham chiếu danh sách hai lần, bù đắp một phiên bản theo một phần tử và nén chúng lại với nhau. Điều này cung cấp cho bạn tất cả các bộ dữ liệu của các phần tử tiếp theo.

my @l := <a b c d e f>; 
say @l Z @l[1..*]; # output: ((a b) (b c) (c d) (d e) (e f)) 

Nếu bạn không muốn tạo một biến tạm thời để giữ danh sách, sử dụng given (và sử dụng do given nếu bạn cần báo cáo kết quả để trả về giá trị):

given <8 2 7 2 6 9 4 9 6 1> { 
    say ($_ Z $_[1..*]).map: -> [$a, $b] { $a+$b }; 
} 

Nếu bạn' tái sử dụng một hàm có hai tham số, bạn có thể muốn flatten danh sách sau khi nén và để map mất hai yếu tố tại một thời điểm:

given <8 2 7 2 6 9 4 9 6 1> { 
    say ($_ Z $_[1..*]).flat.map(&infix:<+>); 
} 
+1

Thank you very much, piojo !! Câu trả lời của bạn thực sự đã giúp !! Có lý do nào bạn đã sử dụng @ [$ a, $ b] thay vì [$ a, $ b] hoặc ($ a, $ b) không? Tất cả đều cho kết quả tương tự. Cảm ơn một lần nữa! – lisprogtor

+0

@smls Cảm ơn, tôi đã thay đổi nó. – piojo

+0

@ lisprogtor Tôi đã không nhận ra bạn có thể phá hoại mà không có một tên biến hoặc sigil. Cảm ơn vì đã cho tôi biết. Tôi đã cập nhật ví dụ. – piojo

Các vấn đề liên quan