Perché il ritorno Math :: :: cartesiano prodotto benedetto gli oggetti?
-
09-10-2019 - |
Domanda
Math :: :: torna cartesiani prodotto un array di oggetti benedetti invece di un semplice array di array. Non riuscivo a capire perché. Io in realtà bisogno di fare qualche lavoro extra (unbless) per utilizzare i risultati ...
Soluzione
Un'alternativa è il modulo Set :: CrossProduct , che produrrà ordinaria , riferimenti ad array unblessed:
use Set::CrossProduct;
my $iter = Set::CrossProduct->new([ \@foo, \@bar ]);
while (my $tuple = $iter->get){
...
}
o ottenere tutte le tuple in una volta:
my @tuples = $iter->combinations;
Altri suggerimenti
Ho aggiunto una funzione cartesian
a :: Gen recentemente:
-
cartesian CODE LIST_of_ARRAYREF
cartesian
calcola il prodotto cartesiano di qualsiasi numero di arbitri matrice, ciascuno che può essere di qualsiasi dimensione. restituisce un generatoreuse List::Gen 'cartesian'; my $product = cartesian {$_[0] . $_[1]} [qw/a b/], [1, 2]; print "@$product"; # 'a1 a2 b1 b2'
Il "generatore" restituito è un array di pigro legato che genererà valori quando gli viene chiesto per loro. Ci sono anche metodi di accesso iterativi e altri:
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 ...
Non so quanto sia grande il set si dovrà lavorare con sono, ma il vantaggio di utilizzare l'approccio di cui sopra è che i requisiti di archiviazione per il generatore rimangono 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
che calcola solo 6 elementi dell'insieme e memorizza nulla.
Come si può vedere dagli esempi, il valore di ritorno di cartesian
è di per sé un oggetto generatore, ma successivi valori di ritorno che dell'oggetto sono qualunque sia il rifcodice passò ai rendimenti cartesian
. Quindi, se volete riferimenti ad array, è semplice come: cartesian {\@_} ...
Inoltre, ciò che lavoro extra hai dovuto fare per affrontare il riferimento beati? Una matrice benedetta è ancora un array in ogni senso salvo quanto tornerà ref
. Se si sta scrivendo la logica interruttore in base al tipo di riferimento, Scalar::Util
di reftype
è quello che si dovrebbe usare.
Benedice array restituiti da cartesian
modo che quando viene eseguito un codice come il seguente
$b = $cartesian $a1, $a2;
$c = $cartesian $b, $a3;
... si può rilevare che $b
è il risultato di una precedente chiamata al modulo.
Facendo un funzionamento del prodotto cartesiano è una cosa banale, se i dati come restituito da quel modulo non soddisfare le vostre esigenze, considerano scrivendo l'operazione da soli da zero.
In ogni caso, ispezionare il codice sorgente del modulo rivela che non è troppo grande.