【问题标题】:F# - Converting nested for-loops to a functional styleF# - 将嵌套的 for 循环转换为函数式样式
【发布时间】:2016-04-01 05:28:29
【问题描述】:

我正在尝试将嵌套的 for 循环转换为更实用的样式。

我一直在搞乱流水线、序列和数组,但无济于事。

这是我所拥有的:

let allCarrierCodes = new List<string>()    
for result in getAllCarrierCodesResults do
        for carrierCode in result do
            allCarrierCodes.Add(carrierCode.ToString())
  • getAllCarrierCodesResults 是“obj list”类型的序列

重写嵌套循环的好方法是什么?

谢谢。

【问题讨论】:

  • 除了重写嵌套循环之外,还可以考虑从“普通”列表 (System.Collections.Generic.List) 切换到不可变的 F# 列表。它将使您可以访问所有 F# 好东西,例如模式匹配。下面是李的回答,那就是let allCodes = getAllCarriesCodes |&gt; Seq.concat |&gt; Seq.map string |&gt; List.ofSeq

标签: f# functional-programming


【解决方案1】:

你可以使用Seq.collect:

let allCodes = Seq.collect id getAllCarrierCodesResults 
               |> Seq.map string)

let allCodes = Seq.collect (Seq.map string) getAllCarrierCodesResults

然后您可以将生成的seq&lt;string&gt; 转换为您想要的具体集合。

【讨论】:

  • 我不会写Seq.collect id,而是使用Seq.concat
  • 另外,您可以利用 F# 4 中的新功能,其中constructors can be used as first-class functions。有了这个,你可以写let allCodes = getAllCarriesCodes |&gt; Seq.concat |&gt; Seq.map string |&gt; ListList的使用,看我上面的评论。
【解决方案2】:

Lee 的回答比这更好,但我只想提一下,您完全可以将那些嵌套循环放在列表理解中,瞧:

let allCarrierCodes =
  [for result in getAllCarrierCodesResults do
     for carrierCode in result do
       yield carrierCode.ToString()]

看起来有点像命令式的,但实际上很实用。

另外,您应该使用string carrierCode 而不是carrierCode.ToString()。保护您免受 NRE 的伤害,并且看起来更实用,以获得额外的奖励 :-)

【讨论】:

  • 如果您建议不要使用.ToString(),为什么在您的回答中使用它?
  • 为了让它尽可能接近 OP 的代码。
猜你喜欢
  • 2021-09-16
  • 2021-12-09
  • 2013-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
  • 2012-11-06
相关资源
最近更新 更多