2011-02-01 3 views
3

sprintf、書式文字列、および文字列のリストを引数とし、リスト内の各要素の文字列がsprintfに適用/折りたたまれていますか?F#文字列のリストにsprintfを適用する

myPrint (sprintf "one: %s two: %s three: %s") ["first"; "second"; "third"];; 

すなわち

は出力

val myPrint : string = "one: first two: second three: third" 

答えて

8
を:「3:第三」 - - その出力にString.Joinにそれほどのいずれかを、または倍使用]近づいている...

をしかし、それはあなたが望むように、単一の文字列が返さ見えます

F#の書式文字列は、静的に既知の数の引数を取るように特別に設計されているので、必要な処理を行うための特別な方法はありません。しかし、このようなものは動作するはずです:

let rec myPrintHelper<'a> (fmt:string) : string list -> 'a = function 
| [] -> sprintf (Printf.StringFormat<_>(fmt)) 
| s::rest -> myPrintHelper<string -> 'a> fmt rest s 

let myPrint fmt = myPrintHelper<string> fmt 

myPrint "one: %s two: %s three: %s" ["first"; "second"; "third"] 

あなたの文字列の"%s" ESの数は、リスト内の文字列の数と一致しない場合、これは実行時に例外がスローされます。

+0

ありがとう、それはまさに私が探していたものです。ただし、上記の実装では、逆順でリストが出力されます。私が変更するにはあまりにも難しくはありません。 –

0
List.map myPrint ["first"; "second"; "third;"] 

がちょうどコンソールにプリントアウトするには...

を新しいsprintf'edリストを返します生み出します... List.iterはリスト内の各値に対して関数を反復し、その関数を実行しますが、avを返さない関数でのみ機能しますアウエー。 「 - > T」Uを - (つまり、printfの...)

マップがかかるので、

let myPrint in = sprintf "%s" in 

が許される任意の他の に任意の形式のリストを変換しますが、もう一度あなたの質問を読んでそれはあなたが望むことをしません。 - あなたは、インデックスを追加し、MAPI、使用することができます( - > 'T - >' int型U)を、あなたは[ "1:最初" を返します

let myPrint index val = sprintf "%d : %s" index val 

としてmyPrintを定義できます。 "2:秒";

let final = List.fold (fun (builder, index) in -> builder.AppendFormat("{0}: {1}", index, in), index + 1) (new StringBuilder()) ["first"; "second"; "third"] 
+0

上記で指定した出力を得るためにmyPrintをどのように定義しますか? –

+0

私は自分の答えを編集しました。 – Massif

関連する問題