2017-09-12 27 views
5

Đây là một ví dụ về mã hiện tại của tôi:Hiện erlang có một danh sách ẩn trong danh sách?

DataSet = [1,2,3,4,5,6,7,8,9]. 

Sequence = [3,4,5,6]. 

ReducedDataSet = lists:foldl(fun(SeqNumber, Output) -> 
           Row = lists:nth(SeqNumber, DataSet), 
           [Row|Output] 
           end, 
           [], 
           Sequence 
          ). 

ReducedDataSet kết thúc lên như [6,5,4,3] và nếu tôi thay đổi nó vào danh sách: foldr, ReducedDataSet sẽ là [3,4,5 , 6].

Tôi không mong đợi điều này như khi hấp thu trái sang phải, giá trị thứ 3 là 3 và nên tiến hành đến 6, nhưng khi hấp thụ phải sang trái, giá trị thứ 3 sẽ là 7, và tiến tới 4.

Điều này có nghĩa là có một số hàng ẩn trong danh sách của tôi, và foldl và foldr chỉ khác nhau theo thứ tự sắp xếp của danh sách cuối cùng?

Trả lời

4

TL; DR

Không, không có chỉ mục ẩn hoặc "số hàng" trong danh sách Erlang.

Thảo luận

Có thể hữu ích để khám phá bản chất của hoạt động danh sách hơn một chút trong bối cảnh danh sách chức năng của "danh sách một loạt các conses" nhiều.

tôi đã viết một lời giải thích của nếp gấp một thời gian lại có thể hữu ích cho bạn: Explanation of lists:fold function

Hãy ghi nhớ rằng danh sách chức năng chỉ có con trỏ mà đi một chiều. Tức là, họ là danh sách được liên kết đơn lẻ. Không có khái niệm về "rownum" hoặc "index" vì nó sẽ nằm trong một mảng kiểu C. Mỗi cuộc gọi đến lists:nth/2 thực sự là duyệt qua danh sách thành phần tử n trước khi trả về phần tử đó.

Chúng tôi có thể viết lists:nth/2 như thế này nếu chúng ta muốn có một phiên bản đó bị treo trên đầu vào xấu (và, nhìn nó lên, nó quay ra rằng it is written almost exactly like this):

nth(1, [Element | _]) -> 
    Element; 
nth(N, [_ | Rest]) when N > 1 -> 
    lists:nth(N - 1, Rest). 

(Như một mặt lưu ý, xem xét not inlining funs that require you to write multi-line definitions as function arguments. ..)

+0

Hãy suy nghĩ điều này trả lời câu hỏi của tôi là tốt nhất tôi đã hỏi nó. Câu trả lời khác là một lời nhắc nhở nhanh về nếp gấp, nhưng như tôi đã nhận ra, câu trả lời là để nhớ rằng đó là danh sách: thứ n đã xác định vị trí trong danh sách. – Philbo

+0

Tôi cũng không phải là người hâm mộ về cách chúng tôi hiện đang viết các chức năng đa dòng - cách tôi viết nó ở trên chỉ phản ánh cách chúng tôi hiện đang thực hiện. Sẽ gửi liên kết của bạn về phía trước để cấp cao của tôi, xem nếu nó làm cho một lập luận thuyết phục hơn tôi đã quản lý. – Philbo

+0

@Philbo Không phải ai cũng đồng ý với tôi rằng việc phân hủy mọi thứ là một ý tưởng hay. Tôi đã thấy rằng các hàm rất thường được đặt tên dễ dàng hơn để xử lý (và tìm tái sử dụng ở đâu đó) so với các nội dung vui nhộn, và trong hầu hết các trường hợp gán một nhãn có ý nghĩa cho một hàm ẩn danh khác trong hàm lớn hơn. Những khả năng đọc này sẽ thắng * thực sự * cộng thêm theo thời gian, đặc biệt khi bạn quay lại làm lại một số mã cũ. Đối với phong cách chung, tôi đã viết một dự án ví dụ cho mục đích đó dựa trên lời khuyên có sẵn của graybeard: https://github.com/zxq9/zuuid – zxq9

4

Tôi nghĩ đây là câu hỏi tổng quát hơn fold.

Nói chung, lần thực hiện như sau: (new_element, acc) -> new_acc

Nếu hoạt động new_element ° acc là giao hoán (ví dụ các sum), foldl và foldr đều giống nhau.

Nếu hoạt động được "nối thêm", có sự khác biệt giữa việc thêm phần tử vào bên trái hoặc bên phải.

[3] ° 4 -> [3, 4] VS 4 ° [3] -> [4, 3]

Tôi không bao giờ nhớ đó là foldlfoldr nhưng tôi nghĩ rằng trái/phải đề cập đến vị trí của ắc ([3] ° 4foldl với định nghĩa này)

+2

Thành thật mà nói, với câu trả lời của bạn, tôi đã nhận ra rằng tôi đang tập trung vào điều sai ở đây.Như bạn nói foldl và foldr chỉ xác định vị trí của các phần tử được thêm vào danh sách mới tích lũy, danh sách của nó: thứ n sử dụng Số liệu gốc tĩnh và xác định từng vị trí. Để liệt kê: nth, phần tử thứ 3 luôn ở vị trí thứ 3, bất kể tôi làm gì với phần tử đó khi tôi đã có nó. – Philbo

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