2009-08-10 5 views
8

Da so etwas wieLiefert Perl garantiert konsistent geordnete Hash-Schlüssel?

foreach (keys %myHash) { 
    ... do stuff ... 
} 

foreach (keys %myHash) { 
    ... do more stuff ... 
} 

Ist Perl in einer konsistenten Reihenfolge über die Tasten iterieren gewährleistet, wenn der Hash nicht verändert wird?

+0

Nur aus Neugier - für was brauchen Sie diese Eigenschaft? – hillu

+1

Wer wählt alles und alles ab? – erjiang

Antwort

26

Yes. Von perldoc -f keys:

Die Schlüssel werden in einer scheinbar zufälligen Reihenfolge zurückgegeben. Die tatsächliche zufällige Reihenfolge unterliegt Änderungen in zukünftigen Versionen von Perl, aber es ist garantiert, um die gleiche Reihenfolge wie die values oder each Funktion produziert wird (vorausgesetzt, dass der Hash nicht geändert wurde). Seit Perl 5.8.1 unterscheidet sich die Reihenfolge selbst zwischen verschiedenen Ausführungen von Perl aus Sicherheitsgründen (siehe "Algorithmische Komplexitätsangriffe" in perldoc perlsec).

(Hervorhebung von mir)

+12

+1 Es wäre großartig, wenn die Leute zumindest versuchen würden, die exzellente Dokumentation zu lesen, die mit Perl geliefert wird. –

-2

Dies ist eine ziemlich riskante Erwartung. Es wird wahrscheinlich, aber warum sich Sorgen machen? Holen Sie Schlüssel im Voraus, speichern Sie das Ergebnis und durchlaufen Sie das gespeicherte Ergebnis. Dann haben Sie garantiert Zugriff auf die Schlüssel in der gleichen Reihenfolge. Es ist gefährlich, an den Rändern unspezifizierter Implementierungsdetails zu arbeiten.

EDIT: Verpasste die "Garantie" in der doc, aber ich denke immer noch, es ist gefährlich zu erwarten, dass dies nie ändern wird. Vor allem, wenn es bessere Möglichkeiten gibt, die gleichen Ziele zu erreichen.

+2

Warum die Scare-Anführungszeichen um "Garantie"?Es ist (a) sehr deutlich gesagt; (b) wird sich wahrscheinlich nicht ändern, weil es wichtig ist, dass 'Schlüssel' und' Werte' in der gleichen Reihenfolge zurückkehren, so dass die beiden korreliert werden können, wenn Sie 'jedes' nicht verwenden können. – derobert

0

Edit:

Obwohl ein normaler Hash eine einheitliche Ordnung hat, im Falle eines tied hash die Reihenfolge der Tasten ist nicht gut definiert, da es benutzergesteuert ist!

Obwohl sich die Reihenfolge der Hash-Schlüssel nicht ändert, sollten Sie sich überdenken, warum Sie dies tun müssen.

Vielleicht können Sie den Hash in einem Durchgang statt zwei verarbeiten?

Sie sollten die Hash-Schlüssel in einem Array als eine defensive Programmierungspraxis speichern, es sei denn, die Größe der Daten ist groß genug, dass ein Duplizieren wäre ein Problem. Als Bonus können Sie die Liste sogar leicht sortieren und im Hash in einer genau definierten Reihenfolge verarbeiten. Z. B.

my @keys = sort keys %myHash; 

Dies vermeidet Probleme mit dem Hash ändern, da Ihr Array Auftrag wird nie, wenn Sie es wollen ändern.

Wenn Sie dies nicht tun, müssen Sie sehr vorsichtig sein, nichts zu tun, das den Hash ändert, sonst ändert sich die Reihenfolge der Elemente. Schauen Sie in das Modul Readonly, um sicherzustellen, dass dieser Hash nie geändert wird.

+0

Ich verstehe es nicht - warum sollten Sie sich in Bezug auf eine Funktion, die getestet, dokumentiert und somit garantiert funktioniert, defensiv verhalten? Dies scheint genauso albern wie mit einem Texteditor und Aufruf von Datei -> Sicher zweimal in der Zeile in der Hoffnung, dass, wenn der erste im Stillen fehlschlägt, der zweite erfolgreich sein wird. – moritz

+2

@moritz: Das Problem besteht nicht darin, dass Perl die Schlüsselreihenfolge ändert (oder nicht), sondern dass sich die Reihenfolge ändern kann, wenn der Hash geändert wird. Diese Antwort schlägt eine defensive Programmtaktik (separates Array plus Readonly) für die zukünftige Wartung der OP-Codebasis vor und hat nichts mit Perl-Interna zu tun. –

+3

Wenn es keine starken Leistungsgründe gibt, versuche ich immer zu sortieren. Wurde zu oft von Code gebissen, der implizit eine bestimmte Reihenfolge erwartet und auf mysteriöse Weise versagt, wenn scheinbar nicht zusammenhängende Änderungen zu einer anderen Reihenfolge der Schlüssel führen. – ysth