how to permute multi arrays with different numbers of element?

V

VZD

Please help me to solve problem, how to permute multi arrays with different
numbers of element? I can make it manually, but what If you have more that
three arrays?

Thanks


# Perl permute multidimensional arrays
#

my @digits1 = qw(1 2);
my @digits2 = qw(1 2);
my @digits3 = qw(a b c);

foreach my $i (@digits1) {
foreach my $j (@digits2) {
foreach my $k (@digits3) {
print "$i$j$k$l\n";
}
}
}
 
D

Dr.Ruud

Please help me to solve problem, how to permute multi arrays with different
numbers of element? I can make it manually, but what If you have more that
three arrays?

Check out `perldoc -f glob`.

my @digits1 = qw(1 2);
my @digits2 = qw(1 2);
my @digits3 = qw(a b c);

Numbered names raise a red flag.
 
R

Randal L. Schwartz

Ruud> Numbered names raise a red flag.

Some call it "code smell". I like that.
 
A

Alan Curry

Please help me to solve problem, how to permute multi arrays with different
numbers of element? I can make it manually, but what If you have more that
three arrays?

Thanks


# Perl permute multidimensional arrays
#

my @digits1 = qw(1 2);
my @digits2 = qw(1 2);
my @digits3 = qw(a b c);

foreach my $i (@digits1) {
foreach my $j (@digits2) {
foreach my $k (@digits3) {
print "$i$j$k$l\n";
}
}
}

This operation is called a "Cartesian product". Knowing that, it should be
easy to find several implementations.
 
M

Martijn Lievaart

(I seem to keep finding situations where I want to be able to say

map my $d { ... } ...

, and I believe the 'my' is enough to stop it being ambiguous. Hmmm.)

I like it. Makes perfect sense.

M4
 
D

Dr.Ruud

Ruud:

Some call it "code smell". I like that.

1. Numbered names smell.
2. Numbered names are code smell.
3. Numbered names make your code smell.
4. Code with numbered names smells.

I still prefer my n-n r-r pattern.
(I would translate "pink panther" to "paarse panter",
though "pink" is normally "roze".)
 
X

xhoster

Dr.Ruud said:
Was glob too obvious?

perl -wle'print for glob "{1,2,3}{4,5,6}{7,8}"'

I haven't tried this on a newer perl, but at least on older ones this
method will get slow and beat the crap out of your hard drive as the list
gets longs. It checks whether each string exists as a filename, but the
results of that check are ignored.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
D

Dr.Ruud

Ruud:

glob doesn't work with arbitrary strings. I suppose you could assume the
OP was only (ever going to be) permuting digits, but I generally dislike
solutions that involve quoting and reparsing. Besides, the question
asked for an arbtrary number of arrays, and I don't know that

glob join "",
map "{$_}",
map { join ",", @$_ }
@digits;

is much more concise than the solution I posted.

Good points. It easily gets ugly:

perl -wle '
my @digits = ( [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, "8,X" ] );
print for glob join "",
map "{$_}",
map join( ",", map quotemeta, @$_ ),
@digits;
'
 
D

Dr.Ruud

I haven't tried this on a newer perl, but at least on older ones this
method will get slow and beat the crap out of your hard drive as the list
gets longs. It checks whether each string exists as a filename, but the
results of that check are ignored.

Why do you think it would go to disk?

<quote src=`perldoc -f glob`>
If non-empty braces are the only wildcard characters used in
the "glob", no filenames are matched, but potentially many
strings are returned.
</quote>

Still, see Ben's reasons to avoid glob.
 
D

Dr.Ruud

Ruud:

Let's have a look, shall we?

~% ktrace -tn perl -e'glob "{1,2}{3,4}"'
~% kdump
<snip>
34066 perl NAMI "13"
34066 perl NAMI "14"
34066 perl NAMI "23"
34066 perl NAMI "24"
~%

So, yes, it goes to the disk, whether it needed to or not. (This is
5.12.2.)

Bug?
 
P

Peter J. Holzer

Why do you think it would go to disk?

Because older ones *do* go to disk?

% strace perl -wle'print for glob "{1,2,3}{4,5,6}{7,8}"'
[...]
lstat64("147", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("148", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("157", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("158", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("167", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("168", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("247", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("248", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("257", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("258", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("267", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("268", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("347", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("348", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("357", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("358", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("367", 0xbf910610) = -1 ENOENT (No such file or directory)
lstat64("368", 0xbf910610) = -1 ENOENT (No such file or directory)
write(1, "147\n", 4147
) = 4
write(1, "148\n", 4148
) = 4
write(1, "157\n", 4157
) = 4
[...]

% perl -v

This is perl, v5.10.1 (*) built for i486-linux-gnu-thread-multi
(with 56 registered patches, see perl -V for more detail)

Copyright 1987-2009, Larry Wall

<quote src=`perldoc -f glob`>
If non-empty braces are the only wildcard characters used in
the "glob", no filenames are matched, but potentially many
strings are returned.
</quote>

This sentence isn't there in 5.10.1. If newer perls don't try to stat
the files any more (note that "no filenames are matched" doesn't
necessarily imply this), then the change was made after 5.10.1

hp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top