#recursion #clojure #split #concatenation
#рекурсия #clojure #разделение #конкатенация
Вопрос:
Как новичка в Clojure, меня беспокоит эта небольшая проблема:
Я хотел бы выполнить итерацию по последовательности и выполнить split
, а затем str
функцию (конкатенации) над элементами последовательности.
Вот моя последовательность:
(("2.660.784") ("2.944.552") ("44.858.797"))
Я хочу получить что-то вроде этого:
("2660784" "2944552" "44858797")
И это моя попытка создать рекурсивное решение для моей проблемы:
(defn old
[squence]
(let [size (count squence)]
(loop [counter 1]
(if (<= counter size)
(apply str (clojure.string/split
(first (first squence))
#"b.b"
))
(old (rest squence)))
)))
И, конечно, это не решение, потому что оно применяется split
и str
только к одному элементу, но я хотел бы повторить это для каждого элемента в squence
. Это squence
продукт какой-то другой функции в моем проекте.
Я определенно что-то упускаю, поэтому, пожалуйста, помогите мне с этим…
Ответ №1:
Самый простой способ написать это с replace
помощью , а не split
/ str
. И как только вы написали функцию, которая может выполнять это преобразование для одной строки, вы можете использовать map
или for
для выполнения этого для последовательности строк. Здесь мне пришлось немного разрушить, поскольку по какой-то причине каждый элемент вашей последовательности сам по себе является другой последовательностью; Я просто вытащил первый элемент.
(for [[s] '(("2.660.784") ("2.944.552") ("44.858.797"))]
(clojure.string/replace s #"b.b" ""))
Комментарии:
1. Обратите внимание, что в clojure следует предпочитать векторы спискам в кавычках, когда это применимо.
2. Привет, прежде всего, спасибо за ответ. Причина, по которой эти строки находятся в отдельных списках (внутри списка), заключается в том, что они являются продуктом моих функций clojure / enlive selector steps, поэтому я не могу с этим связываться. Я делаю это, чтобы я мог разобрать их на числа (точнее, целые числа), в основном для результирующей коллекции я хотел бы применить Java Integer.parse («string») метод. Я на правильном пути, или есть какой-то более простой способ сделать это?
3. @SridharRatnakumar: Производительность. Векторы — это массивы, списки — связанные списки. Массивы, как правило, быстрее, за исключением случаев, когда дело доходит до добавления или удаления элементов.
Ответ №2:
user=> (defn reject-char-from-string
[ch sequence]
(map #(apply str (replace {ch nil} (first %))) sequence))
#'user/reject-char-from-string
user=> (reject-char-from-string . '(("2.660.784") ("2.944.552") ("44.858.797"))
)
("2660784" "2944552" "44858797")
Ответ №3:
Пробовал это?
=> (flatten '(("2.660.784") ("2.944.552") ("44.858.797")))
("2.660.784" "2.944.552" "44.858.797")
Ответ №4:
Это так просто, как это?
(def data '(("2.660.784") ("2.944.552") ("44.858.797")))
(require '[clojure.string :as string])
(map #(string/replace (first %1) "." "") data)
;=> ("2660784" "2944552" "44858797")
Комментарии:
1. В значительной степени, и после того, как я должен преобразовать строки в числа (синтаксический анализ с помощью метода Java integer.parse). Есть ли какое-то более элегантное решение?
2. Как насчет этого? (сопоставление #(-> (первый %1) (строка / замена «.» «») (Целое число / синтаксический анализ)) данные)