Marko: Elegante Lösung für ein Standardproblem gesucht

Hallo Perl-fReaKS,

heute mal ein ganz einfaches Standard-Perl Problem, mir fallen dazu zwar durchaus Lösungsmöglichkeiten ein, aber keine kurze und prägnante, wie es in Perl einfach geben muss.

Das Problem:

eine CSV datei soll in eine Liste von Hashes eingelesen werden. Die Feldbezeichnungen, stehen in der ersten Zeile. Die Liste soll später nur die Daten (ab 2. Zeile enthalten), aber jedes Listenelement ist ein Hash, der als Key die Werte der ersten Zeile benutzt.
Das Feldtrennzeichen ist , es werden keine "" für Strings verwendet.

So, schonmal vielen Dank für die Hilfe in Form von Anregungen, Erklärungen oder sogar einem kleinen Stückchen Code :-)

Gruss

Marko

  1. Hi Marko!

    heute mal ein ganz einfaches Standard-Perl Problem

    So ein aehnliches Problem hatte ich neulich tatsaechlich. In dieser etwas abgwandelten Form entspricht der Code wohl Deiner Aufgabe:

    sub LoadCSV($$$) {
        my ($csvref, $csvname, $separator) = (shift, shift, shift);
        my ($fields, @fields, @row);
        local *CSV;

    open(CSV, "<$csvname") return 0;

    chomp($fields = <CSV>);
        @fields = split($separator, $fields);

    while (<CSV>) {
            chomp;
            push(@$csvref, { });
            @{$csvref->[-1]}{@fields} = split($separator);
        }

    close(CSV);
        return 1;
    }

    @csv = ();
    LoadCSV(@csv, "xyz.csv", '') die("Can't read that fuckin' csv file!\n");

    print(scalar(@csv), " records read.\n\n");
    for (@csv) {
        print("$key=$value\n") while (($key, $value) = each(%{$_}));
        print("\n");
    }

    Ob das nun elegant ist, muss wohl jeder fuer sich selber entscheiden. Mir gefaellt's jedenfalls. ;-)

    Calocybe

  2. Hi!

    Bin mal wieder da... ;)

    eine CSV datei soll in eine Liste von Hashes eingelesen werden. Die Feldbezeichnungen, stehen in der ersten Zeile. Die Liste soll später nur die Daten (ab 2. Zeile enthalten), aber jedes Listenelement ist ein Hash, der als Key die Werte der ersten Zeile benutzt.
    Das Feldtrennzeichen ist , es werden keine "" für Strings verwendet.

    So, schonmal vielen Dank für die Hilfe in Form von Anregungen, Erklärungen oder sogar einem kleinen Stückchen Code :-)

    Ich würde das so machen:

    erstmal die erste Zeile lesen

    Hier noch kein "@", weil sonst das gesamte File

    gelesen wird

    $felderzeile = <DATEI>;

    CR am Ende entfernen

    chomp($felderzeile);

    Dann Aufsplitten:

    @felder = split(//,$felderzeile);

    Array-Zaehler auf 0

    $zeile=0;

    OK, jetzt der Rest:

    while (<DATEI>) {
        # wieder CR weg und aufsplitten
        chomp($_);
        @werte = split(//,$_);
        # und jetzt kopieren wir den Array in den Hash-Array:
        for ($i=0;$i<=$#werte;$i++) {
            $wert{$felder[$i]}[$zeile] = $werte[$i];
        }
        # naechste Zeile...
        $zeile++;
    }

    Ansprechen laest sich das dann z.B. so:

    for ($i=0;$i<$zeile-1;$i++) {
        foreach $key (keys %felder) {
            print $key,"=",$wert{$key}[$i],"\n";
        }
    }

    Statt dem $zeile-Zähler könnte man auch die Perl-Variable $./$NR verwenden, in der die Zeile der Datei steht. So finde ich's aber verständlicher...

    Ciao,
    Mirko