let result =
items
|>List.scan (fun (removed, _) item ->
if removed then true, Some(item) //If already removed, just propagate
elif predicate item then true, None //If not removed but predicate matches, don't propagate
else false, Some(item)) //If not removed and predicate doesn't match, propagate
(false, None)
|>List.choose snd
Trạng thái là bộ tuple. Yếu tố đầu tiên là cờ Boolean cho biết chúng tôi đã xóa một số mục khỏi danh sách. Yếu tố thứ hai là một tùy chọn: Một số khi chúng tôi muốn phát ra mục, Không có cách nào khác.
Dòng cuối cùng lấy các phần tử thứ hai từ các trạng thái và cho mỗi phần tử phát ra giá trị được bao bọc (trong trường hợp Một số) hoặc không làm gì cả (trong trường hợp Không có).
Điều khoản bảo vệ có thể tốt đẹp, nhưng trong trường hợp này tôi nghĩ rằng chúng làm cho nó khó hiểu hơn. Tôi nghĩ chỉ là '| h :: t -> nếu vị từ h sau đó (List.rev acc) @ t else vòng lặp (h :: acc) t' là rõ ràng hơn. – mydogisbox
Lợi thế của câu trả lời này là nó ngừng xử lý khi đạt được giá trị khớp đầu tiên để có thể tiết kiệm rất nhiều công việc. – TheQuickBrownFox
Trong phiên bản đệ quy đuôi, bạn có thể thay đổi trường hợp '[]' để trả về 'danh sách' đầu vào thay vì đảo ngược bộ tích lũy, mà chỉ là danh sách đảo ngược. – TheQuickBrownFox