Как отформатировать строку в Clojure, используя map-indexed и vector - PullRequest
0 голосов
/ 25 мая 2018

Я пытаюсь прочитать содержимое файла в формате:

ID | Имя | Название страны | Номер телефона, например:

1|Austin|Germany|34-554567
2|Mary Jane|Australia|45-78647

Я использую следующий код для извлечения данных из него:

(
  map-indexed
    #(vector %1 %2)
    (
      map #(vec(.split #"\|" %1))
      (
        line-seq (clojure.java.io/reader "test.txt")
      )
    )
)

с этим кодом я получаю этот вывод:

([0 ["1" "Austin" "Germany" "34-554567"]] [1 ["2" "Mary Jane" "Australia" "45-78647"]] [2 ["3" "King Kong" "New-Zealand" "35-467533"]])

Я хочувывод должен быть таким:

ID:["name" "country-name" "phone-number"]
ID:["name" "country-name" "phone-number"]

например:

1:["Austin" "Germany" "34-554567"]
2:["Mary Jane" "Australia" "45-78647"]

где идентификатор должен быть увеличен на 1 (начиная с 1,2,3 и т. Д.), И в каждом результате указывается идентификатор или идентификатор, за которым следуют данные, объединенные с идентификатором, и это должно бытьотсортировано по идентификатору.

Какие изменения я могу внести в свой код, чтобы это произошло?

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

Похоже, ваши данные уже содержат индексы:

(def data
  "1|Austin|Germany|34-554567
   2|Mary Jane|Australia|45-78647
   3|King Kong|New-Zealand|35-467533 ")

(defn fmt [line]
  (let [sections (-> line
                     str/trim
                     (str/split #"\|")) ]
    sections) )

(defn run []
  (let [lines (vec (str/split-lines data)) ]
    (mapv fmt lines)))

(run)

с результатом:

sections => ["1" "Austin" "Germany" "34-554567"]
sections => ["2" "Mary Jane" "Australia" "45-78647"]
sections => ["3" "King Kong" "New-Zealand" "35-467533"]

Если вы хотите выбросить индексы в данных, вы можете сгенерироватьваш собственный, например, так:

(defn fmt [idx line]
  (let [sections      (-> line
                          str/trim
                          (str/split #"\|"))
        sections-keep (rest sections)
        result        (apply vector idx sections-keep)]
    result))

(defn run []
  (let [lines (vec (str/split-lines data))]
    (mapv fmt (range 1 1e9) lines)))

Обновление

Если вы хотите использовать файл на диске, сделайте следующее:

(def data
  "1|Austin|Germany|34-554567
   2|Mary Jane|Australia|45-78647
   3|King Kong|New-Zealand|35-467533 ")

(defn fmt [idx line]
  (let [sections      (-> line
                          str/trim
                          (str/split #"\|"))
        sections-keep (rest sections)
        result        (apply vector idx sections-keep)]
    result))

(defn run [filename]
  (let [lines (vec (str/split-lines (slurp filename)))]
    (mapv fmt (range 1 1e9) lines)))

(let [filename "/tmp/demo.txt"]
  (spit filename data)
  (run filename))
0 голосов
/ 25 мая 2018

Предположение:

(def data
  "1|Austin|Germany|34-554567
   2|Mary Jane|Australia|45-78647
   3|King Kong|New-Zealand|35-467533")

(->> (for [line (clojure.string/split data #"[ ]*[\r\n]+[ ]*")]
       (-> line (clojure.string/split #"\|") rest vec))
     (map vector (rest (range))))

; ([1 ["Austin" "Germany" "34-554567"]]
;  [2 ["Mary Jane" "Australia" "45-78647"]]
;  [3 ["King Kong" "New-Zealand" "35-467533"]])

Хотя я не уверен, почему вы хотите иметь явный автоматически сгенерированный идентификатор в результате и игнорировать серийный номер, который вы получили в исходных данных.

При желании добавьте (into (sorted-map)) в конец, чтобы получить последовательные идентификаторы, сопоставленные со значениями, и это сохранит порядок идентификаторов в отличие от хэш-карты.

0 голосов
/ 25 мая 2018

возможно

(into {}  (map-indexed
       #(vector (inc %1) (rest %2))
       (repeat 2 ["1" "Austin" "Germany" "34-554567"])))
...