Warum Math :: cartesianischen :: Produkt Rückkehr Objekte gesegnet?
-
09-10-2019 - |
Frage
Math :: cartesianischen :: Artikel Renditen ein Array des Sel Objekte anstelle einer einfachen Array von Arrays. Ich konnte nicht herausfinden, warum. Ich brauche eigentlich einige zusätzliche Arbeit (unbless) zu tun, um die Ergebnisse zu verwenden ...
Lösung
Eine Alternative ist das Modul Set :: Crossproduct , die gewöhnlichen ergeben wird , unblessed Array Referenzen:
use Set::CrossProduct;
my $iter = Set::CrossProduct->new([ \@foo, \@bar ]);
while (my $tuple = $iter->get){
...
}
oder erhalten alle Tupel auf einmal:
my @tuples = $iter->combinations;
Andere Tipps
Ich habe eine cartesian
Funktion List :: Gen kürzlich:
-
cartesian CODE LIST_of_ARRAYREF
cartesian
berechnet die kartesisches Produkt von einer beliebigen Anzahl von Array refs, die jede beliebige Größe sein kann. kehrt ein Generatoruse List::Gen 'cartesian'; my $product = cartesian {$_[0] . $_[1]} [qw/a b/], [1, 2]; print "@$product"; # 'a1 a2 b1 b2'
Der „Generator“ zurückgegeben wird, ist ein faules gebunden Array, das Wert erzeugen, wenn sie gefragt. Darüber hinaus gibt es iterative und andere Zugriffsmethoden:
my $pairs = cartesian {@_} [qw/$ @ %/], ['a'..'z'], [1 .. 3];
while (my @tuple = $pairs->next) { # $pairs->reset; #$pairs->index = 5; ...
print @tuple, ', ';
}
# $a1, $a2, $a3, $b1, $b2, $b3, $c1, $c2, $c3, $d1, $d2, $d3, $e1 ...
Ich weiß nicht, wie groß die Sets, die Sie arbeiten werden, aber der Vorteil für den oben beschriebenen Ansatz besteht darin, dass der Speicherbedarf für den Generator bleiben O(1)
my $digits = cartesian {join '' => @_} ([0..9]) x 10;
say for @$digits[10**9 - 3 .. 10**9 + 3];
# 0999999998
# 0999999999
# 1000000000
# 1000000001
# 1000000002
# 1000000003
, die nur 6 Elemente des Satzes berechnet und speichert nichts.
Wie Sie aus den Beispielen sehen können, ist der Rückgabewert von cartesian
selbst ist ein Generator-Objekt, aber das Objekt der nachfolgenden Rückgabewerte sind unabhängig von der Codereferenz zu cartesian
kehrt übergeben. Also, wenn Sie Array Referenzen wollen, es ist so einfach wie: cartesian {\@_} ...
Auch, was zusätzliche Arbeit müssen Sie mit dem gesegneten Bezug zu beschäftigen zu tun? Eine gesegnete Array ist immer noch ein Array in jeder Hinsicht außer dem, was ref
zurückkehren wird. Wenn Sie Schaltlogik schreiben, basierend auf Referenztyp, Scalar::Util
des reftype
ist das, was Sie verwenden sollen.
Es segnet die von cartesian
zurückgegebenen Arrays so, dass, wenn einige Code wie die folgenden ausgeführt wird,
$b = $cartesian $a1, $a2;
$c = $cartesian $b, $a3;
... kann es erkennen, dass $b
ist das Ergebnis eines vorherigen Aufruf zum Modul.
eine kartesische Produktoperation macht dir etwas trivial ist, wenn die Daten als von diesem Modul zurückgegeben nicht Ihre Anforderungen passen, betrachten writting den Betrieb selbst von Grunde auf neu.
Wie auch immer, das Modul Quellcode Inspektion deckt sie nicht zu groß ist.