質問

私は気づきました 数学::カルテシアン::製品 単純な配列の代わりに、祝福されたオブジェクトの配列を返します。理由がわからなかった。結果を使用するには、実際に余分な作業(ブレスなし)を行う必要があります...

役に立ちましたか?

解決

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 モジュールへの以前の呼び出しの結果です。

デカルト製品の操作を行うことは些細なことです。そのモジュールによって返されたデータがニーズに合わない場合は、自分で操作をゼロから書くことを検討してください。

とにかく、モジュールソースコードを検査すると、それがあまり大きくないことが明らかになりました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top