Sembra che non ci sia alcuna funzione nella libreria standard di tipo char -> string -> string
, che inserisce uno char
davanti a (o alla fine di) uno string
. Esistono soluzioni alternative, ad es. utilizzando String.make
o String.blit
. C'è un modo elegante per farlo?Come si aggiunge un carattere a una stringa in OCaml?
risposta
String.make
e String.blit
è un buon modo per farlo, ma sembrano essere imperativi. Personalmente preferisco fare le funzioni infissa utilizzando Char.escaped
e concatenazione di stringhe:
let (^$) c s = s^Char.escaped c (* append *)
let ($^) c s = Char.escaped c^s (* prepend *)
Direi che "Char.escaped" è per usi specializzati come la generazione del codice OCaml come output o la scrittura di messaggi leggibili dall'uomo. Per i casi ordinari, 'String.make 1 c' è probabilmente quello che vuoi. Sembra un po 'maldestro. Le batterie hanno 'BatString.of_char'. –
Grazie per il chiarimento su 'Char.escaped'. Mantengo la risposta invariata, così gli altri lo sanno. – pad
Perché downvoted quando tutto è chiarito dalla risposta e commento di @ JeffreyScofield? – pad
Il codice da @pad è quello che vorrei utilizzare, perché mi piace trattare le stringhe come immutabile, se possibile. Ma non vorrei usare Char.escaped
; è specializzato per quando vuoi la rappresentazione lessicale di un personaggio di OCaml. Quindi, ecco quello che si ottiene se si effettua questo cambiamento:
let prefix_char s c = String.make 1 c^s
let suffix_char s c = s^String.make 1 c
ho fatto un confronto tra l'efficienza dei diversi approcci:
ho scritto un semplice test:
let append_escaped s c = s^Char.escaped c let append_make s c = s^String.make 1 c let append_sprintf s c = Printf.sprintf "%s%c" s c let _ = let s = "some text" in let c = 'a' in for i = 1 to 100000000 do let _ = append_(*escaped|make|sprintf*) s c in() done
L'ho compilato in modo nativo (Intel Core 2 Duo).
ho eseguito il test di tre volte per ogni opzione, cronometraggio con
time
, e calcolando la media tempo reale trascorso.
Ecco i risultati:
s^String.make 1 c
: 7.75s (100%)s^Char.escaped c
: 8.30s (107%)Printf.sprintf "%s%c" s c
: 68.57s (885%)
Giusto per notare, ancora: 'Char.escaped' non fa la stessa cosa di' String.make'. Crea un valore "sfuggito" per il personaggio, in base alle regole lessicali di OCaml. Per vedere questo, prova ad aggiungere una nuova riga (''\ n'') in questo modo. Questo è anche il motivo per cui è un po 'più lento. Per scopi più generali, si desidera utilizzare 'String.make 1 c'. Naturalmente 'Printf.sprintf' è molto più lento, ma incredibilmente flessibile. –
@JeffreyScofield Aggiungo solo questo, quindi le persone non hanno bisogno di provarlo da sé: 'Char.escaped '\ n'' =' "\\ n" '. –
Grazie, forse avrei dovuto dirlo io stesso! Questi commenti sono limitati per essere molto brevi. Ad ogni modo: 'Char.sfuggito '\ n'' ti dà una stringa di due caratteri composta da '' \\ '' e '' n''. 'String.make 1 '\ n'' ti dà una stringa di un carattere composta da'' \ n'', che è più probabile che sia ciò che vuoi. –
L'utilizzo di 'Buffer' è probabilmente più appropriato per stringhe in crescita. –