2013-05-16 12 views
7

Mam ciąg w Clojure i postać, którą chcę wstawić między n-tą i (n + 1) st. Znakiem. Na przykład: Powiedzmy, że string jest "aple" i chcę wstawić kolejny "p" między "p" i "l".Clojure: Idiomatyczny sposób wstawiania znaku w ciąg znaków

(prn 
    (some-function "aple" "p" 1 2)) 

    ;; prints "apple" 
    ;; ie "aple" -> "ap" "p" "le" and the concatenated back together. 

mi znalezienie tego nieco trudne, więc postać Brakuje mi informacji o kilka przydatnych funkcji() może ktoś proszę mi pomóc napisać „Some-funkcja” powyżej, który pobiera ciąg, inny ciąg, pozycja początkowa i pozycja końcowa i wstawia drugi ciąg do pierwszego między pozycją początkową a pozycją końcową? Z góry dziękuję!

Odpowiedz

11

bardziej efektywne niż przy użyciu funkcji seq:

(defn str-insert 
    "Insert c in string s at index i." 
    [s c i] 
    (str (subs s 0 i) c (subs s i))) 

Z REPL:

user=> (str-insert "aple" "p" 1) 
"apple" 

NB. Ta funkcja w rzeczywistości nie dba o typ c lub jego długość w przypadku napisu; (str-insert "aple" \p 1) i (str-insert "ale" "pp" 1) będą również działać (ogólnie, (str c) będą używane, co jest pustym ciągiem, jeśli c jest nil i (.toString c) w innym przypadku).

Ponieważ pytanie dotyczy idiomatycznego sposobu wykonania danego zadania, zauważę również, że uważam za preferowane (jeśli chodzi o "dopasowanie semantyczne" oprócz przewagi wydajności) stosowanie funkcji zorientowanych na ciągi, gdy zajmowanie się konkretnie strunami; obejmuje to subs i funkcje od clojure.string. Zobacz the design notes at the top of the source of clojure.string, aby omówić obsługę ciągów idiomatycznych.

+2

Przy okazji różnica prędkości jest dość wyraźna. Szybki test porównawczy Criterium mówi mi, że '(str-insert" aple "" p "1)' trwa około 180 ns, co jest 12,5 razy mniejsze niż 2,25 μs w wersji opartej na seq. –

+1

Uwaga 'subs' opakowuje' podła '' '' '' '' 'StringBuilder'. Nie sądzę, że można to zrobić lepiej. –

Powiązane problemy