Получение данных в ближайшем будущем - PullRequest
0 голосов
/ 03 июня 2018

У меня есть три текстовых файла как http://paste.debian.net/plain/1027720. Поскольку третий файл имеет следующий формат

Third File

salesID | custID | prodID | itemCount
1|1|1|3
2|2|2|3

Я хочу отобразить таблицу так, чтобы custID должен был быть заменен именем клиента иprodID в описании продукта следующим образом: 1: ["John" "shoes" "3"] То, что я до сих пор делал, это:

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

Как я могу получить и отобразить значения соответственно?

РЕДАКТИРОВАТЬ

"demo_1.txt"
content id|name|address|phone-number
1|John|123 Street|456-4567
2|Smith|123 Here Street|456-4567

"demo_2.txt"
prodID | item | Cost
1|shoes|14.96
2|milk|1.98

1 Ответ

0 голосов
/ 03 июня 2018

Обработка этих данных аналогична обработке файлов CSV.Мне нравится разбивать проблему на функции, которые выполняют линию на вектор и вектор на карту, используя первую строку в качестве заголовка для каждого.

(defn line->vec [s]
  (s/split s #"\|"))

(defn vec->map [desc row]
  (into {}
    (map vector desc row))) ; Map accepts multiple collections

(defn file->maps [filename]
  ; Destructuring here, for easy capturing of header row
  (let [[desc & lines] (->> (slurp filename)
                            (s/split-lines)
                            (map line->vec))
        desc-keys (map keyword desc)]
    (for [line lines]
      (vec->map desc-keys line))))

Для ваших демонстрационных файлов вы можете использовать group-by для генерациикарта, вроде индекса (я вручную исправил форматирование заголовка, но вы захотите сделать это с помощью утилиты fn):

Для (group-by :content-id (file->maps "demo_1.txt"))

{"1" [{:address "123 Street",
       :phone-number "456-4567",
       :name "John",
       :content-id "1"}],
 "2" [{:address "123 Here Street",
       :phone-number "456-4567",
       :name "Smith",
       :content-id "2"}]}

Для(group-by :prodID (file->maps "demo_2.txt"))

{"1" [{:item "shoes", :prodID "1", :cost "14.96"}],
 "2" [{:item "milk", :prodID "2", :cost "1.98"}]}

И затем замените каждый столбец на значение индекса:

(defn replace-value [index idx-key m k]
  (update m k #(get-in index [% 0 idx-key])))

(defn -main [& args]
  (let [customers (group-by :content-id (file->maps "demo1.txt"))
        products (group-by :prodID (file->maps "demo2.txt"))]
    ; Use customers and products to replace some data
    (->> (file->maps "demo_3.txt")
         (map #(replace-value customers :name % :content-id))
         (map #(replace-value products :item % :prodID)))))

И результат:

({:prodID "shoes", :content-id "John", :salesID "1", :itemCount "3"}
 {:prodID "milk", :content-id "Smith", :salesID "2", :itemCount "3"})

Тогда это должно быть простопреобразовать эти карты обратно в нужный вам формат.

...