Tôi thích giải pháp này tốt hơn. Nó tạo ra một chuỗi mới từ chuỗi hiện tại (có nghĩa là nó không cần phải đi qua toàn bộ chuỗi để có được kết quả - điều đó quan trọng nếu bạn đang làm một cái gì đó như xử lý nhật ký, nơi bạn không thể gọi những thứ như Độ dài).
Tôi đã kết thúc bằng văn bản blog post với thông tin chi tiết hơn về cách tôi nhận tại đây.
module Seq =
hãy grouped_by_with_leftover_processing f (f2: 'một danh sách -> danh sách <' a> tùy chọn) (s: seq < 'a>) = hãy grouped_by_with_acc rec (f:' a -> 'một danh sách - > 'một danh sách tùy chọn *' danh sách) acc (ví dụ: IEnumerator < 'a>) = seq { nếu ie.MoveNext() sau đó hãy nextValue, thức ăn thừa = f ie.Current acc nếu nextValue.IsSome sau đó yield nextValue.Giá trị lợi nhuận! thức ăn thừa grouped_by_with_acc f tức là khác hãy REMS = f2 acc nếu rems.IsSome sau đó mang lại rems.Value } seq { năng suất! grouped_by_with_acc f [] (s.GetEnumerator()) }
hãy YieldReversedLeftovers (f: 'một danh sách) = nếu f.IsEmpty sau đó Không khác Một số (List.rev f)
let grouped_by fs = grouped_by_with_leftover_processing f YieldReversedLeftovers s
hãy group_by_length_n ns = hãy grouping_function newValue acc = hãy để newList = newValue :: acc // Nếu chúng ta có chiều dài đúng, trở về // a Một số là giá trị đầu tiên. Điều đó sẽ // được tạo bởi chuỗi. nếu List.length acc = n - 1 thì một số (List.rev newList), [] // Nếu chúng ta không có độ dài phù hợp, // use None (do đó không có gì sẽ được tạo) else None , newList
grouped_by grouping_function s
chuỗi lớn không phải là một vấn đề:
seq {for i in 1..1000000000 - > i} | > Seq.group_by_length_n 3 ;; val it: seq < int danh sách > = seq [[1; 2; 3]; [4; 5; 6]; [7; số 8; 9]; [10; 11; 12]; ...] >
Nguồn
2009-04-06 20:12:00
Câu trả lời hay. Tôi đã gần với điều này với mã của tôi nhưng không hoàn toàn có nó. – gradbot