2009-07-24 5 views
4

Ich kann nicht entscheiden, welcher Ansatz ist mehr (1) idiomatische Perl, (2) effizient, oder (3) "klar".Was ist besser in Perl: ein Array von Hash-Referenzen oder eine Liste von "flachen" Hashes?

Lassen Sie mich durch Code erklären. Erstens kann ich

sub something { 
    ... 
    $ref->{size} = 10; 
    $ref->{name} = "Foo"; 
    $ref->{volume} = 100; 
    push (@references, $ref); 
    ... 
    return @references; 
} 

oder, was ich tun kann

sub something { 
    ... 
    push (@names, "Foo"); 
    $sizes{Foo} = 10; 
    $volumes{Foo} = 100; 
    ... 
    return (\@names, \%sizes, \%volumes); 
} 

Beide tun im Wesentlichen das Gleiche. Wichtig ist, dass ich das Array brauche, weil ich die Reihenfolge einhalten muss.

Ich weiß, es gibt immer mehr als eine Möglichkeit, etwas zu tun, aber dennoch, welche dieser beiden würden Sie bevorzugen?

+1

Können Sie Ihre Aufgaben vertikal ausrichten und auffüllen? Und entfernen Sie die Klammer bei Ihrer Rückkehr und drücken Sie?Das würde das OP viel klarer machen. –

Antwort

10

Anstatt in bedeutungslosen Begriffen wie something zu denken, denke und formuliere das Problem konkret. In diesem Fall scheinen Sie eine Liste von Objekten mit den Attributen name, size und volume zurückzugeben. Wenn man so darüber nachdenkt, gibt es keinen Grund, die zweite Methode überhaupt in Betracht zu ziehen.

Sie können später an Optimierungen denken, wenn Sie Probleme haben, aber selbst wenn Sie dies tun, würden Sie wahrscheinlich mehr von Memoize als durch explodierende Datenstrukturen gewinnen.

Eine Effizienzsteigerung Ich empfehle wird, ist eine Referenz von dieser Subroutine zurück:

sub get_objects { 
    my @ret; 

    while ('some condition') { 
     # should I return this one? 
     push @ret, { 
      name => 'Foo', 
      size => 10, 
      volume => 100, 
     }; 
    } 

    return \@ret; 
} 
+1

danke. Ich dachte, die konkreten Bedingungen würden nur ganz einfache Fragen komplizieren. Btw, ich möchte eine Liste von HTML-Seiten zurückgeben, die Titel, Link, HTML-Quelle und Schlüsselwörter haben. –

5

Ich bevorzuge ersteres. Es hält ein "Paket" von Daten (Größe, Name, Volumen) zusammen und macht viel mehr lesbaren Code.

2

zusammen Ihre zugehörigen Daten halten. Der einzige Grund, große parallele Arrays zu erstellen, ist, dass Sie dazu gezwungen sind.

Wenn Sie besorgt sind über die Geschwindigkeit und Speicherverbrauch, können Sie konstanten Array-Indizes verwenden, um Ihre Namen Felder zugreifen:

use constant { SIZE => 0, NAME => 1, VOLUME => 2, }; 

sub something { 
    ... 

    $ref->[SIZE] = 10; 
    $ref->[NAME] = "Foo"; 
    $ref->[VOLUME] = 100; 

    push @references, $ref; 

    ... 
    return @references; 
} 

Ich habe auch einige Leerzeichen den Code leichter zu machen, hinzugefügt zu lesen.

Wenn ich viele Parameter mit Validierungsregeln und/oder tiefen Datenstrukturen habe, tendiere ich dazu, nach Objekten zu suchen, um meinen Code zu vereinfachen, indem ich die Logik über die Daten mit den Daten verknüpfe. Natürlich, OOP verlangt eine Geschwindigkeitsstrafe, aber ich habe nur selten gesehen, dass dies ein Problem wird.

Für schnelle und schmutzige OOP verwende ich Class :: Struct, die viele Fehler hat. Für Situationen, in denen ich eine Typprüfung benötige, verwende ich Moose oder Mouse (wenn Speicher- oder Startgeschwindigkeit eine große Rolle spielt).

0

Beide Wege könnten für verschiedene Probleme nützlich sein. Wenn Sie immer auf alle Informationen zugreifen, halten Sie sie einfach zusammen. In Ihrem Fall möchten Sie beispielsweise den Namen, den Titel und die Größe einer Webseite verfolgen. Sie arbeiten wahrscheinlich mit allen drei dieser Dinge gleichzeitig, also halten Sie sie zusammen als ein Array von Hash-Referenzen.

Andere Zeiten, können Sie Daten in verschiedene Dinge brechen, die Sie separat verwenden und unabhängig von den anderen Spalten suchen möchten. In diesen Fällen können separate Hashes sinnvoll sein.

Verwandte Themen