なぜMath :: Cartesian :: Product Return Blessed Objectsがあるのですか?
-
09-10-2019 - |
質問
私は気づきました 数学::カルテシアン::製品 単純な配列の代わりに、祝福されたオブジェクトの配列を返します。理由がわからなかった。結果を使用するには、実際に余分な作業(ブレスなし)を行う必要があります...
解決
1つの選択肢はモジュールです セット:: CrossProduct, 、これにより、通常の、添付されていない配列参照が得られます。
use Set::CrossProduct;
my $iter = Set::CrossProduct->new([ \@foo, \@bar ]);
while (my $tuple = $iter->get){
...
}
または、すべてのタプルを一度に取得します:
my @tuples = $iter->combinations;
他のヒント
Aを追加しました cartesian
関数 リスト:: gen 近々:
cartesian CODE LIST_of_ARRAYREF
cartesian
任意のサイズの可能性のある任意の数の配列refのデカルト製品を計算します。ジェネレーターを返しますuse List::Gen 'cartesian'; my $product = cartesian {$_[0] . $_[1]} [qw/a b/], [1, 2]; print "@$product"; # 'a1 a2 b1 b2'
返された「ジェネレーター」は、要求されると値を生成する怠zyな縛られた配列です。反復的およびその他のアクセサの方法もあります。
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 ...
私はあなたが働くセットがどれだけ大きいかはわかりませんが、上記のアプローチを使用することの利点は、ジェネレーターのストレージ要件が残っていることです 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
セットの6つの要素のみを計算し、何も保存しません。
例からわかるように、の返品値 cartesian
それ自体はジェネレーターオブジェクトですが、そのオブジェクトの後続の戻り値は、coderefが渡されたものです cartesian
戻り値。したがって、配列参照が必要な場合は、次のように簡単です。 cartesian {\@_} ...
また、祝福された参照に対処するために、どのような余分な仕事をしなければなりませんでしたか?祝福された配列は、何を除いてあらゆる意味でアレイです ref
戻ります。参照タイプに基づいてスイッチロジックを書き込んでいる場合、 Scalar::Util
's reftype
使用する必要があります。
返された配列を祝福します cartesian
そのため、次のようなコードが実行されたとき
$b = $cartesian $a1, $a2;
$c = $cartesian $b, $a3;
...それはそれを検出できます $b
モジュールへの以前の呼び出しの結果です。
デカルト製品の操作を行うことは些細なことです。そのモジュールによって返されたデータがニーズに合わない場合は、自分で操作をゼロから書くことを検討してください。
とにかく、モジュールソースコードを検査すると、それがあまり大きくないことが明らかになりました。