Clojure: hoe een element van een vector in een andere vector te krijgen

Ik ben erg nieuw bij Clojure en heb problemen met het begrijpen van de werking van vectoren/lijsten/kaarten. Ik probeer de namen van alle klanten in gegevens af te drukken, maar ik kan niet achterhalen hoe. Help alstublieft.

(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))
       )
  )
)

geeft 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]

wat ik wil:

"John Smith"
"Sue Jones"
"Fang Yuhong"
0
line-vector-c is niet gedefinieerd. Ook is voor lui en wordt het niet aanbevolen voor bijwerkingen zoals afdrukken. Gebruik in plaats hiervan doseq .
toegevoegd de auteur exupero, de bron
line-vector-c is niet gedefinieerd. Ook is voor lui en wordt het niet aanbevolen voor bijwerkingen zoals afdrukken. Gebruik in plaats hiervan doseq .
toegevoegd de auteur exupero, de bron
Heb je al die andere soortgelijke vragen bekeken? Het lijkt erop dat veel van jullie in dezelfde klas zitten of iets met hetzelfde huiswerk. Klik op de Clojure-tag en bekijk de vragen, want deze is in principe al een paar keer beantwoord.
toegevoegd de auteur Carcigenicate, de bron
Over het algemeen is het het beste om gegevens te beschouwen als levend in Clojure-gegevensstructuren, in dit geval een vector of reeks kaarten. Het probleem splitst zich dan op in twee: 1. de gegevens in een dergelijke vorm krijgen en 2. het antwoord afleiden en uitbrengen.
toegevoegd de auteur Thumbnail, de bron
Over het algemeen is het het beste om gegevens te beschouwen als levend in Clojure-gegevensstructuren, in dit geval een vector of reeks kaarten. Het probleem splitst zich dan op in twee: 1. de gegevens in een dergelijke vorm krijgen en 2. het antwoord afleiden en uitbrengen.
toegevoegd de auteur Thumbnail, de bron

8 antwoord

Wat je tot nu toe hebt gekregen (enigszins herschreven) 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"]]

Nu wil je elk tuple van strings veranderen in slechts het 2de element van elk tuple. Er zijn een aantal functies die u daarvoor kunt gebruiken: get of nth (beide zijn gebaseerd op nul).

Bijvoorbeeld:

(mapv (fn [l]
        (get (str/split l #"\|")
             1))
      (str/split-lines data))
3
toegevoegd

Wat je tot nu toe hebt gekregen (enigszins herschreven) 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"]]

Nu wil je elk tuple van strings veranderen in slechts het 2de element van elk tuple. Er zijn een aantal functies die u daarvoor kunt gebruiken: get of nth (beide zijn gebaseerd op nul).

Bijvoorbeeld:

(mapv (fn [l]
        (get (str/split l #"\|")
             1))
      (str/split-lines data))
3
toegevoegd

U kunt een lijst met namen krijgen met behulp van

(def names
  (sequence
    (comp
      (map #(str/split % #"\|"))
      (map second))
    (str/split-lines data)))

Druk vervolgens elke naam af met

(doseq [n names]
  (println n))

Ik gebruik vaak reeks en heb transducers samengesteld om gegevens te verkennen, omdat het handig is om transformaties stap voor stap op te bouwen.

1
toegevoegd

U kunt een lijst met namen krijgen met behulp van

(def names
  (sequence
    (comp
      (map #(str/split % #"\|"))
      (map second))
    (str/split-lines data)))

Druk vervolgens elke naam af met

(doseq [n names]
  (println n))

Ik gebruik vaak reeks en heb transducers samengesteld om gegevens te verkennen, omdat het handig is om transformaties stap voor stap op te bouwen.

1
toegevoegd

RegEx gebruiken:

(kaart second (re-seq #"\|(.*?)\|" data))

komt terug:

("John Smith" "Sue Jones" "Fan Yuhong")

Uitleggen:

re-seq

We vragen re-seq om op elke regel de eerste inhoud tussen een paar | te vinden. De ? in de regex betekent dat we een niet hebzuchtige zoekopdracht willen.

(re-seq #"\|(.*?)\|" data)

komt terug:

(["|John Smith|" "John Smith"] ["|Sue Jones|" "Sue Jones"] ["|Fan Yuhong|" "Fan Yuhong"])

kaart

Finally, we use kaart second to visit each element of the list and get only the second string of the vector.

0
toegevoegd

RegEx gebruiken:

(kaart second (re-seq #"\|(.*?)\|" data))

komt terug:

("John Smith" "Sue Jones" "Fan Yuhong")

Uitleggen:

re-seq

We vragen re-seq om op elke regel de eerste inhoud tussen een paar | te vinden. De ? in de regex betekent dat we een niet hebzuchtige zoekopdracht willen.

(re-seq #"\|(.*?)\|" data)

komt terug:

(["|John Smith|" "John Smith"] ["|Sue Jones|" "Sue Jones"] ["|Fan Yuhong|" "Fan Yuhong"])

kaart

Finally, we use kaart second to visit each element of the list and get only the second string of the vector.

0
toegevoegd

Je kunt elke regel splitsen en de tweede kolom op deze manier krijgen

(defn test [xs]
    (->> (str/split-lines xs)       ;split lines
         (map #(str/split % #"\|")) ;get columns
         (map second)))             ;only the second element of each line

en druk het resultaat af

(map println (test data))

of beter met doseq voor alleen afdrukken

(doseq [n (test data)]
  (println n))
0
toegevoegd

Je kunt elke regel splitsen en de tweede kolom op deze manier krijgen

(defn test [xs]
    (->> (str/split-lines xs)       ;split lines
         (map #(str/split % #"\|")) ;get columns
         (map second)))             ;only the second element of each line

en druk het resultaat af

(map println (test data))

of beter met doseq voor alleen afdrukken

(doseq [n (test data)]
  (println n))
0
toegevoegd