Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# Basics: Folding 2 lists together into a string

a little rusty from my Scheme days, I'd like to take 2 lists: one of numbers and one of strings, and fold them together into a single string where each pair is written like "{(ushort)5, "bla bla bla"},\n". I have most of it, i'm just not sure how to write the Fold properly:

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)))
like image 237
evilfred Avatar asked Dec 23 '09 02:12

evilfred


People also ask

How can I recover my facebook password without code?

To reset your password if you're not logged in to Facebook: Click Forgot Password?. Type the email, mobile phone number, full name or username associated with your account, then click Search. Follow the on-screen instructions.


2 Answers

Your missing two things. The initial state of the fold which is an empty string and you can't use list comprehension on tuples in 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 version

let result = 
    List.fold2 
        (fun acc index value -> 
            String.Format("{0}{{(ushort){1}, \"{2}\"}},\n", acc, index, value))
        "" 
        indexes 
        values

If you are concerned with speed you may want to use string builder since it doesn't create a new string every time you append.

let result = 
    List.fold2 
        (fun (sb:StringBuilder) index value -> 
            sb.AppendFormat("{{(ushort){0}, \"{1}\"}},\n", index, value)) 
        (StringBuilder()) 
        indexes 
        values
    |> string
like image 118
gradbot Avatar answered Nov 15 '22 09:11

gradbot


Fold probably isn't the best method for this task. Its a lot easier to map and concat like this:

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"
like image 42
Juliet Avatar answered Nov 15 '22 11:11

Juliet