F#でリストの先頭に対するパターンマッチングの簡単な方法
-
05-09-2019 - |
質問
私はこのようになりますこれは、F#で文字列処理関数を記述しようとしています:
let rec Process html =
match html with
| '-' :: '-' :: '>' :: tail -> ("→" |> List.of_seq) @ Process tail
| head :: tail -> head :: Process tail
| [] -> []
いくつかの要素に対してマイパターンマッチング式(全体'-' :: '-' :: '>'
のこと)ビット醜いあります。それを改善する方法はありますか?また、私は大規模なテキストを処理した場合、効率的なやっているのですか?それとも別の方法がありますか?
を明確化の:私が何を意味するかは、例えば、このような何かを書くことができること:
match html with
| "-->" :: tail ->
解決
私は深刻な文字列操作を行うための文字のリストを使用することは、おそらく理想的ではないことを他の人と同意します。あなたがこのアプローチを使用し続けたいのですがしかし、もし、あなたが求めているものに近い何かを得るための一つの方法は、アクティブパターンを定義することです。たとえばます:
let rec (|Prefix|_|) s l =
if s = "" then
Some(Prefix l)
else
match l with
| c::(Prefix (s.Substring(1)) xs) when c = s.[0] -> Some(Prefix xs)
| _ -> None
次に、あなたはそれが好きで使用することができます:
let rec Process html =
match html with
| Prefix "-->" tail -> ("→" |> List.of_seq) @ Process tail
| head :: tail -> head :: Process tail
| [] -> []
他のヒント
それを改善する方法はありますか?
確かます:
let process (s: string) = s.Replace("-->", "→")
私は大きなテキストを処理した場合にも、私は効率的にやっているのですか?
いいえ、それは信じられないほど非効率的です。割り当てとガベージコレクションは、高価であり、あなたはすべての単一の文字のためにそうしています。
それとも別の方法は何ですか?
Replace
メンバーを試してみてください。それでも解決しない場合は、正規表現を試してみてください。それでも解決しない場合は、(例えばfslex
を使用して)字句解析を記述します。最終的に、あなたは効率のためにしたいことは、ステートマシン文字のストリームを処理し、その場で変異させることによって、その結果を出力する。
私はあなたが、例えば、<文字>リストを使用して文字列を使用して避けるべきだと思いますString.Replace、String.Containsなど可能System.StringとSystem.StringBuilderは、<文字>リスト以外のテキストを操作するためのより良いでしょう。
は、ブライアンが言及したように直接文字列とStringBuilderのを使用した簡単な問題については、おそらく最良の方法です。より複雑な問題については、 FParsec のF#のためのようないくつかの高度な解析ライブラリをチェックアウトすることができます。
この質問はには、いくつかのかもしれあなたの問題に近づいて別の方法のためのアイデアを与えるために、ヘルプ - >行を含むように、<リストを使用しますが、各ラインの中に文字列関数を使用して