Erstellen Sie Hashes von Listen, wie für „alle Tags für ID“ mit Perl dbi

Erstellen Sie Hashes von Listen, wie für „alle Tags für ID“ mit Perl dbi

Ich habe in den dbiDokumenten gesucht und herumgegoogelt, konnte aber nicht herausfinden, ob es eine (dbi) native Möglichkeit gibt, einen Hash von Listen zu erstellen. Das Nächstliegende, was mir einfällt, ist, fetchall_hashrefaber das überschreibt die Ergebnisse und gibt mir nur das letzte Paar zurück. Zur Verdeutlichung: Meine Tabelle ist eine Liste von Paaren von etwas wie „ID, Tag“. Ich möchte alle Zeilen nach ID gruppieren und einen Hash zurückgeben, bei dem der Schlüssel die ID ist und der „Wert“ ein (Ref. auf) die Liste aller seiner Tags. Also im Fall von:

id1, tag1
id1, tag2
id2, tag3
id2, tag1

Ich möchte bekommen:

{'id1' => ['tag1', 'tag2'],
 'id2' => ['tag3', 'tag1'] }

Ist das möglich? Wenn nicht, was ist der beste (effizienteste) Weg, dies nicht nativ zu tun? Der naheliegende Ansatz wäre, einfach eine Kombination aus fetchall_* + push() auszuführen, aber gibt es einen besseren Weg?

Antwort1

Hier ist mein aktueller Ansatz:

my $ret = {};
foreach (@{ $sth->fetchall_arrayref(  ) }) { # returns ref to array
    push  @{ $ret->{ $_->[0] } }, $_->[1] ;
    }
return $ret;

Falls es für irgendjemanden da draußen nützlich ist, können wir währenddessen prüfen, ob es eine bessere Möglichkeit gibt, dies zu tun.


Bearbeiten:

Ich habe einen anderen Ansatz gefunden, der darin besteht, GROUP_CONCATin MySQL für die "Tags" ein eindeutiges Zeichen zu verwenden, das man dann split()in Perl eingibt. Die Abfrage würde dann etwa so lauten:

SELECT id, GROUP_CONCAT(tag, '|')
FROM mytable
GROUP BY tag

Dann in Perl:

my $ret = {};
foreach (@{ $sth->fetchall_arrayref(  ) }) { # returns ref to array
    push  @{ $ret->{ $_->[0] } }, split("|", $_->[1]) ;
    }
return $ret;

Ungetesteter Code, daher gelten die Standardwarnungen.

Der einzige Vorteil, den ich sehe, ist, dass dadurch weniger Zeilen aus der Datenbank zurückgegeben werden und Sie daher weniger Iterationen des Foreach-Befehls haben. Vielleicht kann jemand diesen Code profilieren und uns mitteilen, ob es bei den Ansätzen signifikante Geschwindigkeitsunterschiede gibt.

verwandte Informationen