loops - 如何打破对 FSharp 中列表的迭代?
问题描述
当第一项匹配条件时,我想停止迭代列表。
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
let list2 = [1; 2; 9]
list1 |> List.iter (fun item ->
match List.contains item list2 with
| false -> printfn " Not Present %A" item
| true -> printfn "%A" item)
我只想打印此处不存在的第一个项目,在这种情况下为 3。在功能性地编写代码时如何做到这一点?
解决方案
函数世界中迭代的最终基础是递归:你的函数计算一些东西,然后调用自己进行下一步。或者它决定停止,然后它不调用自己。简单的。
您的特殊情况非常适合这种范式:
let rec loop list =
match list with
| [] -> () // no more list - just return
| head::tail ->
if List.contains head list2
then loop tail // deciding to call myself
else printfn " Not Present %A" head // deciding not to call myself
loop list1 // Kick off the process
但是呢iter
?好吧,模块中的所有这些花哨的功能List
——包括iter
——都建立在相同的递归方案之上。他们也决定是否在每一步都打电话给自己。对于其中一些,您可以通过参数影响决策,而对于另一些则不能。
碰巧iter
你不能。iter
将始终调用自己进行下一步,因此它将始终遍历整个列表。你无能为力。
但是还有其他功能可以影响是否递归的决定。其中有很多,但对于您的目的,我认为List.tryFind
最适合。它接受另一个函数作为参数,它应该返回true
或false
。如果返回true
,tryFind
将停止迭代并返回当前元素。正是你需要的。
list1 |> List.tryFind (fun x ->
if List.contains x list2
then false
else printfn " Not Present %A"; true
)
推荐阅读
- c# - 从 Controller 向 Microsoft Teams 发送消息
- php - 带有 guzzle 的 POST 返回 417
- r - 如何根据另一个数据集中的值过滤一个数据集中的日期和时间
- selenium - 无法在 QAF 中实现 DataTable 黄瓜功能
- amazon-web-services - 如何使用 CLI 获取任何给定区域的所有 pod 详细信息
- python - 如何使用 ModbusTCP 协议将 sensor_1 和 sensor_2 的值从 slave-PC 传输到 master-PC?
- r - R - 结合两个数据表元素的简单方法是什么?
- javascript - onclick,按钮向下移动,为什么会这样?
- android - Android Compose-Navigation 2.4.0-alpha2 崩溃并出现 NoSuchMethodError
- flutter - 无法根据设备大小初始化变量