Question

Je suis en train d'écrire une fonction de traitement de cordes en fa #, qui ressemble à ceci:

let rec Process html =
  match html with
  | '-' :: '-' :: '>' :: tail -> ("→" |> List.of_seq) @ Process tail
  | head :: tail -> head :: Process tail
  | [] -> []

Mon modèle d'expression correspondant à l'encontre de plusieurs éléments est un peu laid (toute chose '-' :: '-' :: '>'). Est-il possible de faire mieux? Aussi, est-ce que je fais efficace si je devais traiter de grands textes? Ou est-il une autre façon?

Précision : ce que je veux dire est, par exemple, être capable d'écrire quelque chose comme ceci:

match html with
| "-->" :: tail -> 
Était-ce utile?

La solution

Je suis d'accord avec les autres que l'utilisation d'une liste de caractères pour faire la manipulation de chaînes graves est probablement pas idéal. Cependant, si vous souhaitez continuer à utiliser cette approche, une façon d'obtenir quelque chose proche de ce que vous demandez est de définir un modèle actif. Par exemple:

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

Ensuite, vous pouvez l'utiliser comme:

let rec Process html =  
  match html with  
  | Prefix "-->" tail -> ("→" |> List.of_seq) @ Process tail  
  | head :: tail -> head :: Process tail  
  | [] -> []

Autres conseils

  

Est-il possible de faire mieux?

Bien sûr:

let process (s: string) = s.Replace("-->", "→")
  

Aussi, est-ce que je fais efficace si je devais traiter de grands textes?

Non, il est incroyablement inefficace. la collecte des ordures et allocation est cher et que vous faites ainsi, pour chaque caractère.

  

Ou est-il une autre façon?

Essayez l'élément Replace. Si cela ne fonctionne pas, essayez une expression régulière. Si cela ne fonctionne pas, écrire un lexer (par exemple en utilisant fslex). En fin de compte, ce que vous voulez pour l'efficacité est une machine d'état du traitement d'un flux de caractères et la sortie de son résultat par muter en place.

Je pense que vous devriez éviter d'utiliser la liste et en utilisant des chaînes et par exemple String.Replace, String.Contains, etc. System.String et System.StringBuilder sera beaucoup mieux pour manipuler le texte que la liste .

Pour des problèmes simples, en utilisant String et StringBuilder directement comme Brian mentionné est probablement la meilleure façon. Pour des problèmes plus complexes, vous pouvez consulter une bibliothèque d'analyse sophistiquée comme FParsec pour F #.

Cette question peut-être quelques-uns aider à vous donner des idées pour une autre façon d'aborder votre problème -. en utilisant la liste <> pour contenir des lignes, mais en utilisant des fonctions de chaîne dans chaque ligne

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top