Pourquoi Math :: :: cartésien retour produit des objets bénis?
-
09-10-2019 - |
Question
Math :: cartésiennes :: retours produit un tableau d'objets bénis au lieu d'un tableau simple des tableaux. Je ne pouvais pas comprendre pourquoi. En fait, je dois faire pour utiliser les résultats des travaux supplémentaires (unbless) ...
La solution
Une alternative est le module Set :: CrossProduct , qui donnera ordinaire , les références de tableau unblessed:
use Set::CrossProduct;
my $iter = Set::CrossProduct->new([ \@foo, \@bar ]);
while (my $tuple = $iter->get){
...
}
Ou procurez-vous tous tuples à la fois:
my @tuples = $iter->combinations;
Autres conseils
J'ai ajouté une fonction cartesian
:: Gen récemment:
-
cartesian CODE LIST_of_ARRAYREF
cartesian
calcule le produit cartésien d'un certain nombre de références de tableau, chaque qui peut être de toute taille. renvoie un générateuruse List::Gen 'cartesian'; my $product = cartesian {$_[0] . $_[1]} [qw/a b/], [1, 2]; print "@$product"; # 'a1 a2 b1 b2'
Le « générateur » de retour est un tableau lié paresseux qui va générer des valeurs lorsqu'on lui a demandé pour eux. Il y a aussi itératives et d'autres méthodes d'accès:
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 ...
Je ne sais pas comment grand les jeux que vous allez travailler sont, mais l'avantage d'utiliser l'approche ci-dessus est que les conditions de stockage du générateur restent 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
qui calcule seulement 6 éléments de l'ensemble, et rien magasins.
Comme vous pouvez le voir dans les exemples, la valeur de retour de cartesian
lui-même est un objet générateur, mais les valeurs suivantes de retour de cet objet sont tout le coderef passé à retourne cartesian
. Donc, si vous voulez des références de tableau, il est aussi simple que: cartesian {\@_} ...
En outre, ce travail supplémentaire avez-vous dû faire pour traiter la référence bénie? Un tableau béni est encore un tableau dans tous les sens, sauf pour ce qui ref
retournera. Si vous écrivez une logique de commutation en fonction du type de référence, le Scalar::Util
de reftype
est ce que vous devez utiliser.
Il bénit les tableaux retournés par cartesian
de sorte que lorsque du code comme suit est exécuté
$b = $cartesian $a1, $a2;
$c = $cartesian $b, $a3;
... il peut détecter que $b
est le résultat d'un appel précédent au module.
Faire une opération de produit cartésien est quelque chose de trivial, si les données réexpédiée par ce module ne correspond pas à vos besoins, envisagez-vous l'opération d'écriture à partir de zéro.
Quoi qu'il en soit, inspecter le code source du module révèle ce n'est pas trop grand.