2015-06-30 3 views
2

Каким будет идиоматический способ написания следующей функции?Clojure - идиоматический способ записи split-first и split-last

(split-first #"." "abc.def.ghi") ;;=>["abc", "def.ghi"] 
(split-last #"." "abc.def.ghi") ;;=>["abc.def", "ghi"] 

Существует очевидное (некрасиво?) Решение с использованием split, но я уверен, что есть более элегантные решения? Может быть, с помощью regexes/indexOf/split-with?

+6

split first is just '(clojure.string/split" abc.def.ghi "#" \. "2)' – cfrick

+0

@cfrick Это очень элегантно. Если у вас есть что-то для «split-last» одинаково хорошо, я с радостью принимаю ваш ответ. – nha

ответ

1

Для сплит-первых, лучший подход был бы:

(defn split-first [re s] 
    (clojure.string/split s re 2)) 

(split-first #"\." "abc.def.ghi") 
=> ["abc" "def.ghi"] 

(split-first #"<>" "abc<>def<>ghi") 
=> ["abc" "def<>ghi"] 

Один из подходов к разделенным последний должен использовать отрицательное опережения утверждение:

(defn split-last [re s] 
    (let [pattern (re-pattern (str re "(?!.*" re ")"))] 
    (split-first pattern s))) 

(split-last #"\." "abc.def.ghi") 
=> ["abc.def" "ghi"] 

(split-last #"<>" "abc<>def<>ghi") 
=> ["abc<>def" "ghi"] 
+3

Хорошая идея, но вам придется также «перевернуть» регулярное выражение. Прямо сейчас ваше решение будет работать только для палиндрома. –

+0

Спасибо за отзыв - я переключился на решение, используя отрицательное утверждение lookahead – toolkit

1

Если вы не обязательно должны регулярному_выражению Соответствующее это будет работать:

(defn index-of 
    [^String s c] 
    (.indexOf s c)) 

(defn last-index-of 
    [^String s c] 
    (.lastIndexOf s c)) 

(defn split-at-index-fn 
    [f c s] 
    (let [i (f s c)] 
    ; I do not know what you want returned if no match is found 
    (when-not (neg? i) 
     [(.substring s 0 i) (.substring s (inc i))]))) 

(def split-first 
    (partial split-at-index-fn index-of)) 

(def split-last 
    (partial split-at-index-fn last-index-of)) 

Это не совсем идиоматично, потому что это в основном просто Java-взаимодействие.

+0

, вы можете сохранить несколько символов, и если вам не нравятся внешний вид взаимодействия, используя 'subs' вместо' .substring', но meh – cfrick

+0

когда совпадения не найдено, он должен вернуть пустой вектор (я думаю, что это наиболее логично, не стесняйтесь) – nha

+1

@nha, хорошо, это довольно легко реализовать, изменив 'when-not' to' if -not' и возвращает пустой вектор в else-block. – ponzao

Смежные вопросы