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 ...

È stato utile?

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 generatore

    use 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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top