I am very new to Clojure and am having difficulties understanding the operations of vectors/lists/maps. I am trying to print out the names of all the customers in data, but I cannot figure out how. Please help.
(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")
(defn test
[]
(let [lines (str/split-lines data)
line-vecs-1 (mapv #(str/split % #"\|" ) lines)]
(for [x line-vector-c] (print (line-vector-c 1))
)
)
)
gives me:
[2 Sue Jones 43 Rose Court Street 345-7867][2 Sue Jones 43 Rose Court Street
345-7867][2 Sue Jones 43 Rose Court Street 345-7867]
what I want:
"John Smith"
"Sue Jones"
"Fang Yuhong"
What you've got so far (slightly rewritten) is:
(mapv (fn [l]
(str/split l #"\|"))
(str/split-lines data))
(str/split-lines data)
splits the lines into a sequence of strings:
["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"]
(mapv #(str/split % #"\\|") lines)
splits each line into tuples of strings:
[["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"]]
Now you want to transform each tuple of strings into just the 2nd element of each tuple. There are a couple of functions you could use for that: get
or nth
(both are zero-based).
For example:
(mapv (fn [l]
(get (str/split l #"\|")
1))
(str/split-lines data))
You can get a list of names using
(def names
(sequence
(comp
(map #(str/split % #"\|"))
(map second))
(str/split-lines data)))
Then print each name with
(doseq [n names]
(println n))
I often use sequence
and composed transducers to explore data, as it's convenient for building up transformations one step at a time.
You can split each line and get the second column like this
(defn test [xs]
(->> (str/split-lines xs) ;split lines
(map #(str/split % #"\|")) ;get columns
(map second))) ;only the second element of each line
and print the result
(map println (test data))
or better using doseq for printing only
(doseq [n (test data)]
(println n))
(map second (re-seq #"\|(.*?)\|" data))
returns:
("John Smith" "Sue Jones" "Fan Yuhong")
We ask re-seq
to find at each line the first content between a pair of |
. The ?
in the regex means we want a non greedy search.
(re-seq #"\|(.*?)\|" data)
returns:
(["|John Smith|" "John Smith"] ["|Sue Jones|" "Sue Jones"] ["|Fan Yuhong|" "Fan Yuhong"])
Finally, we use map second
to visit each element of the list and get only the second string of the vector.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.