Hoe string in Clojure te formatteren door kaart geïndexeerd en vector te gebruiken

I am trying to read content from a file which is in the format :

ID|Name|Country-Name|Phone-Number eg:

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

Ik gebruik de volgende code om gegevens van te halen:

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

met deze code krijg ik deze uitvoer:

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

Ik wil dat de output is zoals:

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

eg:

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

waarbij ID moet worden verhoogd met 1 (start vanaf 1,2,3 enzovoort) en elk resultaat geeft de identiteit of ID weer, gevolgd door de gegevens die zijn verenigd met de ID en moet worden gesorteerd op een ID.

Welke wijzigingen voer ik in mijn code aan om dit te laten gebeuren?

0
het lijkt erop dat wat je vraagt ​​heel dicht in de buurt komt van wat je krijgt.
toegevoegd de auteur manandearth, de bron
Bedoel je om een ​​kaart te maken die met ID is ingetoetst? Probeer (in {} uw-uitvoer)
toegevoegd de auteur Hendrik Poernama, de bron
Ja, ik probeer het id-nummer in mijn tekstbestand toe te wijzen aan wat ik als een uitvoer krijg. Zodat ik het op het einde gemakkelijk kan sorteren
toegevoegd de auteur Prishu, de bron
Ja, ik probeer het id-nummer in mijn tekstbestand toe te wijzen aan wat ik als een uitvoer krijg. Zodat ik het op het einde gemakkelijk kan sorteren
toegevoegd de auteur Prishu, de bron
@manandearth eigenlijk wat ik nu krijg past niet op mijn daadwerkelijke uitvoer. Bovendien vind ik het moeilijk om alles als een vector toe te wijzen en alle waarden met hun index op te halen
toegevoegd de auteur Prishu, de bron
@manandearth eigenlijk wat ik nu krijg past niet op mijn daadwerkelijke uitvoer. Bovendien vind ik het moeilijk om alles als een vector toe te wijzen en alle waarden met hun index op te halen
toegevoegd de auteur Prishu, de bron

5 antwoord

Het lijkt erop dat uw gegevens al indexen bevatten:

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

met resultaat:

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

Als je de indexen in de gegevens weg zou willen gooien, zou je je eigen kunnen genereren zoals:

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

Bijwerken

Als u een schijfbestand wilt gebruiken, doet u het volgende:

(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
toegevoegd
Ik heb alleen de spit toegevoegd om de creatie van het bestand te tonen. Als je er al een hebt, heb je dat duidelijk niet nodig.
toegevoegd de auteur Alan Thompson, de bron
in uw bijgewerkte antwoord is dit wat ik begrijp. U probeert gegevens in een bestand met de naam demo.txt te plaatsen en vervolgens dat bestand te lezen met behulp van slurp. In fmt-functie hebt u trim- en gesplitste bewerkingen toegepast en vervolgens in run-defn zijn uw toewijzingsvector door fmt als een argument door te geven. Verbeter mij alsjeblieft als ik het fout heb. Tussen haakjes, ik heb al een bestand van waaruit ik gegevens lees. Is er een behoefte om een ​​nieuwe te maken zoals demo.txt . Dingen stuiteren over mijn hoofd.
toegevoegd de auteur Prishu, de bron

Het lijkt erop dat uw gegevens al indexen bevatten:

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

met resultaat:

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

Als je de indexen in de gegevens weg zou willen gooien, zou je je eigen kunnen genereren zoals:

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

Bijwerken

Als u een schijfbestand wilt gebruiken, doet u het volgende:

(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
toegevoegd
Ik heb alleen de spit toegevoegd om de creatie van het bestand te tonen. Als je er al een hebt, heb je dat duidelijk niet nodig.
toegevoegd de auteur Alan Thompson, de bron
in uw bijgewerkte antwoord is dit wat ik begrijp. U probeert gegevens in een bestand met de naam demo.txt te plaatsen en vervolgens dat bestand te lezen met behulp van slurp. In fmt-functie hebt u trim- en gesplitste bewerkingen toegepast en vervolgens in run-defn zijn uw toewijzingsvector door fmt als een argument door te geven. Verbeter mij alsjeblieft als ik het fout heb. Tussen haakjes, ik heb al een bestand van waaruit ik gegevens lees. Is er een behoefte om een ​​nieuwe te maken zoals demo.txt . Dingen stuiteren over mijn hoofd.
toegevoegd de auteur Prishu, de bron

Een gok:

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

Hoewel ik niet zeker weet waarom u een expliciete, automatisch gegenereerde ID in het resultaat wilt hebben, negeert u het serienummer dat u in de oorspronkelijke gegevens hebt.

Voeg eventueel (in (gesorteerde map)) toe aan het einde, zodat u de sequentiële ids toegewezen krijgt aan waarden, en dit behoudt de ID-volgorde in tegenstelling tot een hash-map.

0
toegevoegd
U kunt slurp gebruiken om bestandsinhoud als een tekenreeks te krijgen, als u tenminste het absolute pad gebruikt. De "uitvoer" die u beschrijft is geen Clojure-gegevensstructuur, dus kan deze niet door een Clojure-functie worden geproduceerd. Wilt u dat het in plaats daarvan wordt afgedrukt? Misschien wilt u het invoegen in een gesorteerde kaart ?
toegevoegd de auteur NikoNyrh, de bron
Er zijn een paar functies voor het ophalen van een element uit een vector, zoals nth en get . Ze kunnen ook werken als "functies", bijvoorbeeld (["Austin" "Duitsland" "34-554567"] 1) evalueert naar "Duitsland" .
toegevoegd de auteur NikoNyrh, de bron
Hallo @ NikoNyrh, kunt u alstublieft uw antwoord bijwerken met het mijne aangezien ik een klein probleempje tegenkom tijdens het ophalen van gegevens uit een tekstbestand en het toepassen van uw genoemde bewerking erop.
toegevoegd de auteur Prishu, de bron
Kun je me alsjeblieft vertellen hoe ik een waarde kan ophalen van (([1 ["Austin" "Duitsland" "34-554567"]]) zoiets als een [1] geef resultaat 1, een [2] geef resultaat "Austin" enz.
toegevoegd de auteur Prishu, de bron

kan zijn

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

kan zijn

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