Convert vector of lists into vector of vectors

2020-04-21 02:32发布

问题:

I have the following data in a .txt file:

1|John Smith|123 Here Street|456-4567
2|Sue Jones|43 Rose Court Street|345-7867
3|Fan Yuhong|165 Happy Lane|345-4533

I get the data and convert it to a vector using the following code:

(def custContents (slurp "cust.txt"))
(def custVector (clojure.string/split custContents #"\||\n"))
(def testing (into [] (partition 4 custVector )))

Which gives me the following vector:

[(1 John Smith 123 Here Street 456-4567) (2 Sue Jones 43 Rose Court Street 
345-7867) (3 Fan Yuhong 165 Happy Lane 345-4533)]

I would like to convert it into a vector of vectors like this:

[[1 John Smith 123 Here Street 456-4567] [2 Sue Jones 43 Rose Court Street 
345-7867] [3 Fan Yuhong 165 Happy Lane 345-4533]]

回答1:

I would do it slightly differently, so you first break it up into lines, then process each line. It also makes the regex simpler:

(ns tst.demo.core
  (:require
    [clojure.string :as str] ))

(def data
"1|John Smith|123 Here Street|456-4567
2|Sue Jones|43 Rose Court Street|345-7867
3|Fan Yuhong|165 Happy Lane|345-4533")

  (let [lines       (str/split-lines data)
        line-vecs-1 (mapv #(str/split % #"\|" ) lines)
        line-vecs-2 (mapv #(str/split % #"[|]") lines)]
    ...)

with result:

lines => ["1|John Smith|123 Here Street|456-4567" 
          "2|Sue Jones|43 Rose Court Street|345-7867" 
          "3|Fan Yuhong|165 Happy Lane|345-4533"]

line-vecs-1 => 
   [["1" "John Smith" "123 Here Street" "456-4567"]
    ["2" "Sue Jones" "43 Rose Court Street" "345-7867"]
    ["3" "Fan Yuhong" "165 Happy Lane" "345-4533"]]

line-vecs-2 => 
   [["1" "John Smith" "123 Here Street" "456-4567"]
    ["2" "Sue Jones" "43 Rose Court Street" "345-7867"]
    ["3" "Fan Yuhong" "165 Happy Lane" "345-4533"]]

Note that there are 2 ways of doing the regex. line-vecs-1 shows a regex where the pipe character is escaped in the string. Since regex varies on different platform (e.g. on Java one would need "\|"), line-vecs-2 uses a regex class of a single character (the pipe), which sidesteps the need for escaping the pipe.


Update

Other Clojure Learning Resources:

  • Brave Clojure
  • Clojure CheatSheet
  • ClojureDocs.org
  • Clojure-Doc.org (similar but different)


回答2:

> (mapv vec testing)

=> [["1" "John Smith" "123 Here Street" "456-4567"]
    ["2" "Sue Jones" "43 Rose Court Street" "345-7867"]
    ["3" "Fan Yuhong" "165 Happy Lane" "345-4533"]]