gpt4 book ai didi

f# - 返回 fitler 中的条件?

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

我有以下代码来过滤 Seq 并在未返回任何内容时返回错误。

let s = nodes
|> Seq.filter(fun (a, _, _, _) -> if a.ToLower().Contains(key1)) // condition 1
then true
else false // Error message should have Key1
|> Seq.filter(....) // condition 2
|> Seq.filter(....) // condition 3
.....
|> Seq.filter(function // condition N
| _, Some date, _, _ -> date >= StartPeriod
| _ -> false // put StartPeriod in the final message s is not empty before this step
)

if Seq.isEmpty s
then sprintf "Failed by condition 1 (%s) or condition 2 (%s) .... or condition N (Date > %s)"
key1, ...., (StartPeriod.ToShortDateSTring())
else ....

最终的错误信息sprintf会包含所有的过滤条件。这是一种让代码只返回那些(或只是最后一个)使 s 为空的方法吗?


根据 rmunn 的回答,我修改了它以返回所有有助于清空列表的过滤器。

let rec filterSeq filterList input msgs =
match filterList with
| [] -> input, msgs
| (label, filter) :: filters ->
let result = input |> Seq.filter filter
if result |> Seq.isEmpty then
printfn "The \"%s\" filter emptied out the input" label
Seq.empty, (List.append msgs [label])
else
filterSeq filters result (List.append msgs [label])

let intFiltersWithLabels = [
"Odd numbers", fun x -> x % 2 <> 0
"Not divisible by 3", fun x -> x % 3 <> 0
"Not divisible by 5", fun x -> x % 5 <> 0
"Even numbers", fun x -> x % 2 = 0
"Won't reach here", fun x -> x % 7 <> 0
]

{ 1..20 } |> filterSeq intFiltersWithLabels <| List.empty

最佳答案

我要做的是制作一个过滤器列表,以及一个一次应用它们的递归函数。如果刚刚应用的过滤器返回一个空序列,则停止,打印刚刚清空输入的过滤器,并返回该空序列。否则继续循环递归函数,依次采用列表中的 next 过滤器,直到您最终没有输入或者您已经运行了整个过滤器列表并且在通过后仍然有一些输入剩余所有过滤器。

下面是一些示例代码来说明我的意思。请注意我是如何在每个过滤器函数前面放置标签的,这样我就不会看到像“<fun:filtersWithLabels@4> 过滤器清空了输入”这样的输出,而是我会看到每个过滤器的合理的人类可读标签。

let rec filterSeq filterList input =
match filterList with
| [] -> input
| (label, filter) :: filters ->
let result = input |> Seq.filter filter
if result |> Seq.isEmpty then
printfn "The \"%s\" filter emptied out the input" label
Seq.empty
else
filterSeq filters result

let intFiltersWithLabels = [
"Odd numbers", fun x -> x % 2 <> 0
"Not divisible by 3", fun x -> x % 3 <> 0
"Not divisible by 5", fun x -> x % 5 <> 0
"Even numbers", fun x -> x % 2 = 0
"Won't reach here", fun x -> x % 7 <> 0
]

{ 1..20 } |> filterSeq filtersWithLabels
// Prints: The "Even numbers" filter emptied out the input

如果您想打印所有 过滤器直到清空输入的过滤器,那么您只需将printfn 调用移到if 之外的一行。表达。一旦输入为空,递归就会停止,这意味着您不会在清空输入的过滤器之后看到任何 printfn 调用。

请注意,我编写函数的方式假定您的原始输入不会为空。如果您的原始输入为空,则该函数会将清空输入归功于第一个过滤器,并将打印第一个过滤器的标签。您可以通过在检查空结果之前检查空输入来轻松解决这个问题,但我没有打扰,因为这只是演示代码。如果您的实际输入在实际用例中可能为空,请注意这一点。

更新:如果您需要返回标签列表,而不仅仅是打印它们,那么将其作为您通过 filterSeq 传递的第二个参数功能。像这样:

let matchingFilters filterList input =
let rec filterSeq filterList labelsSoFar input =
match filterList with
| [] -> input, [] // Note NO labels returned in this case!
| (label, filter) :: filters ->
let result = input |> Seq.filter filter
if result |> Seq.isEmpty then
Seq.empty, (label :: labelsSoFar)
else
filterSeq filters (label :: labelsSoFar) result
let result, labels = filterSeq filterList [] input
result, List.rev labels

let filtersWithLabels = [
"Odd numbers", fun x -> x % 2 <> 0
"Not divisible by 3", fun x -> x % 3 <> 0
"Not divisible by 5", fun x -> x % 5 <> 0
"Even numbers", fun x -> x % 2 = 0
"Won't reach here", fun x -> x % 7 <> 0
]

{ 1..20 } |> matchingFilters filtersWithLabels
// Returns: ["Odd numbers"; "Not divisible by 3"; "Not divisible by 5"; "Even numbers"]

关于这个版本的函数有几点需要注意:听起来你想要的是,如果过滤器一直运行而没有清空输入,那么你不希望返回任何过滤器标签。如果我误解了你,请替换 | [] -> input, []符合 | [] -> input, labelsSoFar获取输出中的所有标签。第二点要注意的是,我已经改变了这个函数的“形状”:它不返回一个序列,而是返回一个二元组(结果序列,过滤器标签列表)。如果结果序列不为空,则过滤器标签列表将为空,但如果结果序列最终为空,则过滤器标签列表将包含所有已应用的过滤器,而不仅仅是所有减少输入大小的过滤器。

如果您真正需要的是检查输入的大小是否减小并打印过滤掉某些东西的过滤器标签,那么请查看 Funk 的答案以了解如何检查,但是请注意 Seq.length必须遍历整个原始序列并应用所有过滤器直至该点,每次。所以这是一个缓慢的操作。如果您的输入数据集很大,那么最好坚持使用 Seq.empty逻辑。试用它并决定什么最适合您的需求。

关于f# - 返回 fitler 中的条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50651948/

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