2009-12-23 15 views
5

benim Şema günlerden biraz paslı bir araya 2 listeleri Katlanabilir, ben 2 listeleri almak istiyorum "{(ushort) 5," bla bla bla "}, \ n" gibi yazılmıştır. Ben bunun çoğu var, ben düzgün Fold yazmayı pek emin değilim:F # Temelleri: bir dize

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))) 

cevap

10

Eksik iki şeyiniz. Boş bir dize olan katın ilk durumu ve F # içindeki tupllarda liste kavramasını kullanamazsınız. Eğer hız konusunda endişeleriniz varsa

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 versiyonu

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

Eğer yeni bir dize ekleyin.Yani her zaman yaratmaz çünkü dize oluşturucu kullanmak isteyebilirsiniz.

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

o {} {ve} olmalıdır yerine \} ve \ ait {biçiminde, ben bu yanlış :) – evilfred

+0

güzel yakalamak var, yazı güncellendi doğruluk uğruna. – gradbot

1

Sana List.fold2 istediğini düşünüyorum. Bazı nedenlerden dolayımodülünde fold2 üye var, ancak Seq yapmıyor. Ardından, zip ile tamamen boşaltabilirsiniz.

senin adında değişkenler türleri ve sizin için umut sonucun tipi hepsi örtülü olan, bu yüzden yardım etmek zordur, ancak dizeleri listesini toplamaya çalışıyoruz eğer

çizgisinde bir şey düşünebilirsiniz
let result = pairs |> Seq.fold 
    (fun prev (l, r) -> 
      String.Format("{0}, \{(ushort){1}, \"{2}\"\}\n", prev, l, r) 
    "" pairs 

Benim F #/Caml yüzden yanlış argümanlar sırasını olabilir çok paslı olduğunu. Ayrıca dize oluşumunuzun ikinci dereceden olduğunu unutmayın; Kendi kodda ben bu satırlar boyunca daha şeyle gider:

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

let result = String.concat ", " strings 

Bu, kuadratik zaman maliyeti olmaz ve onu takip etmek biraz daha kolay. MSDN’ü kontrol ettim ve fold2’da doğru argüman sırasına sahip olduğumu düşünüyorum.

Ben F # Çaml biliyorum ve bu yüzden detaylarını ya da yanlış argümanlar sırasını olabilir unutmayın.

8

Katlama muhtemelen bu görev için en iyi yöntem değildir. Böyle Onun bir harita daha kolay çok ve concat:

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" 
0

Belki de bu:

F # bazen daha iyi şart gitmek edilir ile
let strBuilder = new StringBuilder() 
for (i,v) in Seq.zip indexes values do 
    strBuilder.Append(String.Format("{{(ushort){0}, \"{1}\"}},\n", i,v)) 
    |> ignore 

...

0

map2 veya fold2 doğru yoldur gitmek. İşte benim alabilir (||>) operatörü kullanılarak verilmiştir: tabii

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"