我有这样一行代码:
list |> List.mapi (fun i x -> y, i)
Run Code Online (Sandbox Code Playgroud)
(假设 y 是已经定义的类型)
但我想返回具有某些条件的元素(例如过滤它)
我不能这样写:
list |> List.mapi (fun i x -> if 'condition' then y, i)
Run Code Online (Sandbox Code Playgroud)
因为它也需要其他条件,而我没有“其他”情况。我也没有设法同时使用过滤器,因为我还需要返回正确的索引,如果我过滤列表,索引将被更改。有任何想法吗?
编辑 到现在为止,我是这样实现的:
list |> List.mapi (fun i a -> if (a = None) then O, i else X, i) |> List.filter (fun (a,i) -> a = O)
Run Code Online (Sandbox Code Playgroud)
对于其他情况,我给出了无用的 X,我只是为了能够在此之后写入条件并删除 X 条件。它起作用了,这就是我想要的结果。但我相信有更好的解决方案。
让我再补充一个答案:根据您的问题和评论,我了解到您希望根据值按条件过滤列表,同时保留原始索引。我不确定结果是否应该由固定值列表和原始索引组成,或者您想要映射。以下允许两者:
let indexedFilterMap p f =
List.indexed
>> List.filter (snd >> p)
>> List.map (fun (i, x) -> f x, i)
Run Code Online (Sandbox Code Playgroud)
如果您需要映射的索引(因为问题标题包括mapi
):
let indexedFilterMapi p f =
List.indexed
>> List.filter (snd >> p)
>> List.map f
Run Code Online (Sandbox Code Playgroud)
或者,如果您需要过滤器的索引:
let indexedFilteriMap p f =
List.indexed
>> List.filter p
>> List.map (fun (i, x) -> f x, i)
Run Code Online (Sandbox Code Playgroud)
组合应该很简单。
然后可以使用这些:
let list = ['a'; 'b'; 'c']
let condition = (<>) 'b'
let y = "fixed value"
indexedFilterMap condition (fun _ -> y) list // [("fixed value", 0); ("fixed value", 2)]
let m (i, _) = sprintf "fixed value %i" i
indexedFilterMapi condition m list // ["fixed value 0"; "fixed value 2"]
let c (i, _) = i <> 1
indexedFilteriMap c (fun _ -> y) list // [("fixed value", 0); ("fixed value", 2)]
Run Code Online (Sandbox Code Playgroud)