F#只有当它们不是null或空格时才能连接字符串数组

Jam*_*ieS 0 c# arrays f# concatenation

我有下面的F#代码,它用于连接4个字符串,用空格分隔,只包括那些不是null或完全是空格的.

let street = 
    split.[5..8] 
    |> Array.filter (String.IsNullOrWhiteSpace >> not)
    |> String.concat " " 
Run Code Online (Sandbox Code Playgroud)

这非常有效,但性能不如下面的C#实现.

var street = "";
if (!string.IsNullOrWhiteSpace(items[5]))
    street += items[5];
if (!string.IsNullOrWhiteSpace(items[6]))
    street += string.IsNullOrWhiteSpace(street) ? items[6] : " " + items[6];
if (!string.IsNullOrWhiteSpace(items[7]))
    street += string.IsNullOrWhiteSpace(street) ? items[7] : " " + items[7];
if (!string.IsNullOrWhiteSpace(items[8]))
    street += string.IsNullOrWhiteSpace(street) ? items[8] : " " + items[8];
return street;
Run Code Online (Sandbox Code Playgroud)

有没有办法可以在F#中实现相同的实现方式,而不是使用内联函数?

Way*_*ner 5

这是一个删除显式迭代和下标的变体,可以通过传入序列而不是直接引用split来修改为适用于seq的任何集合.

let otherStreet = 
  let combine (sb:StringBuilder) (s:String) =
     if sb.Length = 0 then
        sb.Append s
     else
        (sb.Append " ").Append s

  split.[5..8] 
     |> Seq.filter (String.IsNullOrWhiteSpace >> not)
     |> Seq.fold combine (StringBuilder())
     |> (fun sb -> sb.ToString())
Run Code Online (Sandbox Code Playgroud)

无论何时我需要从序列中积累结果,我倾向于使用折叠而不是显式循环.代码中可能存在拼写错误和/或思考,因为我没有编译器方便验证它.我还打赌这个版本的执行情况比你的实现差一些,但它可以很容易地与非索引集合一起使用作为权衡.