Archiv verlassen und diese Seite im Standarddesign anzeigen : Hashvalues in neuen Hash
Servus,
Mal ne Frage. Ich habe zwei Subroutinen in denen jweils ein Hash (anonymer) mit Werten gefüllt wird.
Mich interessieren aber jeweils nur die Values der Hashes und möchte ich diese jetzt in einen neuen Hash tun, so das einer Key und der andere Value wird.
Geht das und wenn ja wie mache ich das am besten?
Danke
Vorausgesetzt sie haben gleich viele Einträge ja.
Jepp....die haben gleich viele Einträge!
Wie macht man das nun? Im Hauptprogramm verknüpfen oder in einer extra Routine?.....muss hier auch mich Referenzen arbeite, was das ganze noch zusätzlich erschwert.
Versuchs mir bitte erstma so zu erklären, bevor ich unnötig Code poste.
Danke
EDIT: Zur zeit sehen die Einträge folgendermaßen aus
HASH 1
1.1.1 => Name1
1.1.2 => Name2
HASH 2
1.2.1 => Wert1
1.2.2 => Wert2
...das müsste jetzt so ein, dass jetzt Name1 (neuer Key) und Wert1 der Value dazu passt.
EDIT2: Hat sich erledigt. Habs hinbekommen!
Das ist ansich aber nicht ganz trivial weil hashes unsortiert sind das heißt wenn
die Relation Name1=>Wert1 nicht zufällig sein soll muss man da eventuell ein paar Dinge beachten. Abgesehen davon ist es der Community gegenüber nett wenn man die Lösung die man gefunden hat beschreibt/erläutert damit Leute mit ähnlichen Problemen besser geholfen ist.
In meinem Fall war es so, dass jeweils die letzte Zahl eines Keys in beiden Hashes gleich was. Daraufhin habe ich einen Vergleich mit zwei verschachtelten Schleifen gemacht. Die erste Schleife merkt sich die letzte Zahl und in der zweiten findet der Vergleich mit Keys (letzte Zahl) statt.
Code kann ich bei Bedarf gern noch posten.
Jetzt habsch aber nochmal ne andere Frage. Wie schreibe ich einen Hash mit Key und Value in eine Datei?
thx
Indem du die Datei öffnest und eine Abbildung ala
Key Value
oder
Key => Value
in die Datei schreibst:
open(HASHCACHE,">hashcache.txt") || die "Can't open hashcache.txt: $!";
foreach $keyval (keys(%hash)) {
print HASHCACHE "$keyval $hash{$keyval}\n";
}
close HASHCACHE;
eViL_oNe
04.06.2008, 00:41
In meinem Fall war es so, dass jeweils die letzte Zahl eines Keys in beiden Hashes gleich was. Daraufhin habe ich einen Vergleich mit zwei verschachtelten Schleifen gemacht. Die erste Schleife merkt sich die letzte Zahl und in der zweiten findet der Vergleich mit Keys (letzte Zahl) statt.
es wäre vielleicht interessant, wenn du zu diesem Weg auch das Ziel beschreibst, damit man beurteilen kann, ob beide zueinander passen. Hashes mit linearen Suchen zu beackern klingt für mich jedenfalls erstmal nicht nach state-of-the-art ;)
Danke Alamar!
@eViL_oNe
es wäre vielleicht interessant, wenn du zu diesem Weg auch das Ziel beschreibst, damit man beurteilen kann, ob beide zueinander passen. Hashes mit linearen Suchen zu beackern klingt für mich jedenfalls erstmal nicht nach state-of-the-art ;)
Wie könnte man es denn besser machen? Muss dazu sagen, dass ich kein Perlprofi bin und sicher den umständlichsten Weg gegangen bin. Aber zumindest funzt es, dass steht bei mir erstmal an erster Stelle.
Verbesserungsvorschläge nehme ich aber gern entgegen.
mfg
Timi
Jan Krüger
04.06.2008, 10:25
Jetzt habsch aber nochmal ne andere Frage. Wie schreibe ich einen Hash mit Key und Value in eine Datei?
Wenn du die Sachen später auch nochmal mit einem Script auslesen willst, schau dir die Perl-Module Data::Dumper und Storable an.
thx....
Das mit der Datei hat sich erledigt. Ist zum umständlich für mein Vorhaben.
eViL_oNe
04.06.2008, 22:31
Wie könnte man es denn besser machen? Muss dazu sagen, dass ich kein Perlprofi bin und sicher den umständlichsten Weg gegangen bin. Aber zumindest funzt es, dass steht bei mir erstmal an erster Stelle.
Verbesserungsvorschläge nehme ich aber gern entgegen.
mfg
Timi
da du nirgendwo schreibst, was du damit eigentlich erreichen willst, kann man auch schlecht Verbesserungsvorschläge benennen.
OK....dann mal bissl was zum Hintergrund.
Über SNMP frage ich zum einen den Interfacestatus und zum anderen den Inferfacenamen ab. Beides gibt einen Hash in der Form von.....
OID --------------> Value
1.1.1.1 ----------> up
1.1.1.2 ----------> down
und
OID -------------> Value
1.1.2.1 ---------> eth0
1.1.2.2 ---------> eth1
zurück.
Die OID ist natürlich länger, aber soll ja nur ein BSP sein. Da mir das aber so nix nutzt und für mich nur die Values beides Hashes interessant sind (für die Ausgabe), muss ich ja die beiden Hashes irgendwie vereinen. Jetzt erkennt man, dass jeweils die letzte Ziffer der OID's in beiden Hashes gleich ist und diese zusammen gehören. d.h. OID 1.1.1.1 gehört zu 1.1.2.1, was wiederrum anzeigt, das der Status von eth0 "up" ist usw.
Und wie oben schon gesagt, nehme ich mir in der ersten Schleife die 1.1.1.1 vor....merke mir jetzt die letzte Zahl (die 1) und in der zweiten Schleife durchlaufe ich alle OID's mit 1.1.2.x und suche mir dort die 1 und speichere alles in einem neuen Hash.
eViL_oNe
06.06.2008, 21:55
der bessere Ansatz sollte sein, wenn du gleich beim Abrufen der Werte den Hashkey entsprechend "normalisierst"
Aus deinen Ausführungen schließe ich, dass die Normalisierungsfunktion folgende wäre:
1. splitte den key mit separator '.'
2. neuer key => vierter (oder auch letzter) split-wert
mit diesem Wissen kannst du erstmal beide Hashes normalisieren. Danach haben beide die gleichen Keys so dass der Rest einfach sein sollte!
#!/usr/bin/perl
use strict;
my %hash1 = (
"1.1.1.1" => "up",
"1.1.1.2" => "down"
);
my %hash2 = (
"1.1.2.1" => "eth0",
"1.1.2.2" => "eth1"
);
sub normalizeKey
{
my ($keyToNormalize) = @_;
my @keyList = reverse(split(/\./, $keyToNormalize));
return $keyList[0];
}
sub normalizeHash
{
my ($hashRef) = @_;
my %normalizedHash;
foreach my $key(keys(%{$hashRef}))
{
$normalizedHash{normalizeKey($key)} = $hashRef->{$key};
}
return %normalizedHash;
}
my %networks;
%hash1 = normalizeHash(\%hash1);
%hash2 = normalizeHash(\%hash2);
foreach my $key(keys(%hash1))
{
$networks{$hash2{$key}} = $hash1{$key};
}
foreach my $key(keys(%networks))
{
print "$key -> " . $networks{$key} . "\n";
}
Ausgabe:
eth1 -> down
eth0 -> up
Nutzen: Eine verschachtelte foreach-Schleife hat natürlich die Komplexität O(n²). Hier haben wir drei einfache foreach-Schleifen und damit die Komplexität O(n) (vorausgesetzt, die split-Funktion hat konstante Ausführungszeit -- notfalls kann man sich hier noch sicherlich einen Geschwindigkeitszuwachs mit string-Operationen statt regex-Matching erkaufen!). Dies ist für größere Datenmengen optimaler!
Vielen Dank....werds mal austesten....morgen dann ;)
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.