F#基础:将两个列表合并成一个字符串

F#基础:将两个列表合并成一个字符串,f#,functional-programming,F#,Functional Programming,从我的计划时代开始,我有点生疏了,我想拿两个列表:一个是数字,一个是字符串,然后把它们折叠成一个字符串,每一对都写得像“{(ushort)5,“blablablabla”}、\n”。我有大部分,只是不知道如何正确地书写折叠: let splitter = [|","|] let indexes = indexStr.Split(splitter, System.StringSplitOptions.None) |> Seq.toList let values = valueS

从我的计划时代开始,我有点生疏了,我想拿两个列表:一个是数字,一个是字符串,然后把它们折叠成一个字符串,每一对都写得像“{(ushort)5,“blablablabla”}、\n”。我有大部分,只是不知道如何正确地书写折叠:

let splitter = [|","|]
let indexes = 
  indexStr.Split(splitter, System.StringSplitOptions.None) |> Seq.toList 
let values = 
  valueStr.Split(splitter, System.StringSplitOptions.None) |> Seq.toList

let pairs = List.zip indexes values
printfn "%A" pairs

let result = pairs |> Seq.fold
    (fun acc a -> String.Format("{0}, \{(ushort){1}, \"{2}\"\}\n", 
                                acc, (List.nth a 0), (List.nth a 1)))

我想您需要
列表。fold2
。由于某种原因,
List
模块有一个
fold2
成员,但
Seq
没有。然后您可以完全省去
zip

你命名变量的类型和你希望得到的结果的类型都是隐式的,所以很难帮助,但是如果你想积累字符串列表,你可以考虑沿着

行的一些东西。
let result = pairs |> Seq.fold
  (fun prev (l, r) -> 
          String.Format("{0}, \{(ushort){1}, \"{2}\"\}\n", prev, l, r) 
  "" pairs
我的F#/Caml已经生锈了,所以我的论点顺序可能有误。还要注意,你的弦是二次的;在我自己的代码中,我将使用以下内容:

let strings = 
   List.fold2 (fun ss l r -> 
                 String.format ("\{(ushort){0}, \"{1}\"\}\n", l, r) :: ss)
              [] indexes values

let result = String.concat ", " strings
这不会花费你的时间,而且更容易理解。我已经检查了MSDN,并且相信我在
fold2
上的参数顺序是正确的


请记住,我知道Caml而不是F#,因此我可能有错误的细节或论点顺序。

你遗漏了两件事。折叠的初始状态为空字符串,不能对F#中的元组使用列表理解

折叠版本

let result = 
    List.fold2 
        (fun acc index value -> 
            String.Format("{0}{{(ushort){1}, \"{2}\"}},\n", acc, index, value))
        "" 
        indexes 
        values
如果您关心速度,您可能希望使用字符串生成器,因为它不会在每次追加时创建新字符串

let result = 
    List.fold2 
        (fun (sb:StringBuilder) index value -> 
            sb.AppendFormat("{{(ushort){0}, \"{1}\"}},\n", index, value)) 
        (StringBuilder()) 
        indexes 
        values
    |> string

折叠可能不是完成此任务的最佳方法。这样更容易绘制和绘制地图:

let l1 = "a,b,c,d,e".Split([|','|])
let l2 = "1,2,3,4,5".Split([|','|])
let pairs =
    Seq.zip l1 l2
    |> Seq.map (fun (x, y) -> sprintf "(ushort)%s, \"%s\"" x y)
    |> String.concat "\n"
也许这是:

let strBuilder = new StringBuilder()
for (i,v) in Seq.zip indexes values do
     strBuilder.Append(String.Format("{{(ushort){0}, \"{1}\"}},\n", i,v))
     |> ignore

有了F#有时最好是强制执行…

map2或fold2是正确的方法。下面是我使用
(| |>)
操作符的示例:

let l1 = [| "a"; "b"; "c"; "d"; "e" |]
let l2 = [| "1"; "2"; "3"; "4"; "5" |]
let pairs = (l1, l2) ||> Seq.map2 (sprintf ("(ushort)%s, \"%s\""))
                      |> String.concat "\n"

当然应该是{{和}}而不是\}和\{在格式中,我弄错了:)
let l1 = [| "a"; "b"; "c"; "d"; "e" |]
let l2 = [| "1"; "2"; "3"; "4"; "5" |]
let pairs = (l1, l2) ||> Seq.map2 (sprintf ("(ushort)%s, \"%s\""))
                      |> String.concat "\n"