私は気づいたMath::Cartesian::Product配列の単純な配列の代わりにblessedオブジェクトの配列を返します。なぜ私は理解できませんでした。私は実際にMath :: Cartesian :: Productはなぜ祝福されたオブジェクトを返しますか?
答えて
1つの選択肢は、通常、blessされていない配列参照が得られるモジュールSet::CrossProduct、次のとおりです。
use Set::CrossProduct;
my $iter = Set::CrossProduct->new([ \@foo, \@bar ]);
while (my $tuple = $iter->get){
...
}
あるいは、一度にすべてのタプルを取得:
my @tuples = $iter->combinations;
それはcartesian
によって返された配列を祝福...結果を使用する(unbless)いくつかの余分な作業を行う必要があるので、次のようにいくつかのコードが実行されると
$b = $cartesian $a1, $a2;
$c = $cartesian $b, $a3;
...それを前回のモジュール呼び出しの結果であることを検出することができます。
デカルト積の演算を行うのは簡単ですが、そのモジュールから返されたデータがニーズに合わない場合は、最初から操作を書き込むことを検討してください。
とにかく、モジュールのソースコードを調べると、それほど大きくないことがわかります。
を私は最近List::Genにcartesian
機能を追加しました:
cartesian CODE LIST_of_ARRAYREF
は任意の数の配列参照の任意の数のデカルト積を計算します。返された「発電機」は彼らのために尋ねられたときの値を生成します怠惰tieされた配列である発電機
use List::Gen 'cartesian'; my $product = cartesian {$_[0] . $_[1]} [qw/a b/], [1, 2]; print "@$product"; # 'a1 a2 b1 b2'
を返します。反復および他のアクセサメソッドにもあります
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
自体はジェネレータオブジェクトですが、そのオブジェクトの後続の戻り値は、渡されたコードリファレンスがcartesian
になっても返されます。あなたは配列参照をしたいのであれば、それは同じくらい簡単です:cartesian {\@_} ...
また
、あなたは祝福された参照に対処するために行うために余分なものを仕事を持っていましたか? blessed配列はまだref
が返す以外のすべての意味で配列です。参照タイプに基づいてスイッチロジックを作成する場合は、Scalar::Util
のreftype
を使用する必要があります。
'Set :: CrossProduct'は良い選択肢です。http://search.cpan.org/perldoc/Set::CrossProduct –
を参照してください。Sinanの良い選択肢と相殺されて、代わりに悪い選択肢があります:my @cartesian = do {local $ "= '、'; {{@ foo } {@ bar}>}; 配列にglobメタキャラクタが含まれていても、これは高速ではありますが、それは* fun *ではありませんか? – Hugmeir