gpt4 book ai didi

f# - 根据谓词将列表拆分为列表列表

转载 作者:行者123 更新时间:2023-12-01 08:41:34 26 4
gpt4 key购买 nike

(我知道 this question ,但它与序列有关,这不是我的问题)

鉴于此输入(例如):

let testlist = 
[
"*text1";
"*text2";
"text3";
"text4";
"*text5";
"*text6";
"*text7"
]

let pred (s:string) = s.StartsWith("*")

我希望能够调用 MyFunc pred testlist并得到这个输出:
[
["*text1";"*text2"];
["*text5";"*text6";"*text7"]
]

这是我目前的解决方案,但我不太喜欢嵌套的 List.revs(忽略它以 Seq 作为输入的事实)
let shunt pred sq =
let shunter (prevpick, acc) (pick, a) =
match pick, prevpick with
| (true, true) -> (true, (a :: (List.hd acc)) :: (List.tl acc))
| (false, _) -> (false, acc)
| (true, _) -> (true, [a] :: acc)

sq
|> Seq.map (fun a -> (pred a, a))
|> Seq.fold shunter (false, [])
|> snd
|> List.map List.rev
|> List.rev

最佳答案

有一个List.partition F# 核心库中的函数(如果您想实现它只是为了让它工作而不是学习如何自己编写递归函数)。使用这个函数,你可以这样写:

> testlist |> List.partition (fun s -> s.StartsWith("*"))
val it : string list * string list =
(["*text1"; "*text2"; "*text5"; "*text6"; "*text7"], ["text3"; "text4"])

请注意,此函数返回一个元组而不是返回列表列表。这与您想要的有点不同,但如果谓词只返回 true 或 false,那么这更有意义。
partition的实现返回元组的函数也更简单一些,因此它可能对学习有用:
let partition pred list = 
// Helper function, which keeps results collected so
// far in 'accumulator' arguments outTrue and outFalse
let rec partitionAux list outTrue outFalse =
match list with
| [] ->
// We need to reverse the results (as we collected
// them in the opposite order!)
List.rev outTrue, List.rev outFalse
// Append element to one of the lists, depending on 'pred'
| x::xs when pred x -> partitionAux xs (x::outTrue) outFalse
| x::xs -> partitionAux xs outTrue (x::outFalse)

// Run the helper function
partitionAux list [] []

关于f# - 根据谓词将列表拆分为列表列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2071056/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com