Основы F#: Сворачивание 2 списков вместе в строку

немного ржавый с моих дней Схемы, я хотел бы взять 2 списка: одно из чисел и одна из строк, и сворачивают их вместе в единственную строку, где каждая пара записана как "{(ushort)5, "bla bla bla"}, \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)))
5
задан Norman Ramsey 23 December 2009 в 02:32
поделиться

5 ответов

Твои недостающие две вещи. Начальное состояние папки, которая является пустой строкой, и вы не можете использовать понимание списка на кортежах в F#.

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 (index, value) -> 
        String.Format("{0}{{(ushort){1}, \"{2}\"}},\n", acc, index, value)) ""

fold2 версии

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
10
ответ дан 18 December 2019 в 08:28
поделиться

Думаю, вам нужен List.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# и поэтому могу ошибиться с деталями или порядком аргументов.

.
1
ответ дан 18 December 2019 в 08:28
поделиться

Падение, наверное, не самый лучший метод для этой задачи. Его намного проще сопоставить и сравнить следующим образом:

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"
8
ответ дан 18 December 2019 в 08:28
поделиться

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"
0
ответ дан 18 December 2019 в 08:28
поделиться

Возможно, это:

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# иногда лучше идти обязательно...

0
ответ дан 18 December 2019 в 08:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: