UpTide - 4 years ago 144
Perl Question

# Simplifying Conditional Statement [Perl]

I have a 3d matrix and I need to check if several elements equals a value (target value could be different for each element in the future).

Is there any way to simplify the if conditional at the end? I am hoping there would be some way to setup a 'conditional' matrix and compare them while ignoring elements that don't matter in the condition.

Any hints?

currently my code is:

``````use warnings;
use strict;

#fancy matrix
my @matrix;

#set to a blank 3d test matrix
for my \$i (0 .. 6) {
for my \$j (0 .. 6) {
for my \$k  (0 .. 2) {
\$matrix[\$i][\$j][\$k] = 0;
}
}
}

#set some values for matrix

for my \$j (0..2, 4..6) {
my \$i = 4;
for my \$k  (0 .. 2) {
\$matrix[\$i][\$j][\$k] = 1;
}
}
for my \$i (0..2, 4..6) {
my \$j = 4;
for my \$k  (0 .. 2) {
\$matrix[\$i][\$j][\$k] = 1;
}
}

#the conditional problem child
if (\$matrix[0][4][0] == 1 and \$matrix[0][4][1] == 1 and \$matrix[0][4][2] == 1 and \$matrix[1][4][0] == 1 and \$matrix[1][4][1] == 1 and \$matrix[1][4][2] == 1 and \$matrix[2][4][0] == 1 and \$matrix[2][4][1] == 1 and \$matrix[2][4][2] == 1 and \$matrix[4][4][0] == 1 and \$matrix[4][4][1] == 1 and \$matrix[4][4][2] == 1 and \$matrix[5][4][0] == 1 and \$matrix[5][4][1] == 1 and \$matrix[5][4][2] == 1 and \$matrix[6][4][0] == 1 and \$matrix[6][4][1] == 1 and \$matrix[6][4][2] == 1 and \$matrix[4][0][0] == 1 and \$matrix[4][0][1] == 1 and \$matrix[4][0][2] == 1 and \$matrix[4][1][0] == 1 and \$matrix[4][1][1] == 1 and \$matrix[4][1][2] == 1 and \$matrix[4][2][0] == 1 and \$matrix[4][2][1] == 1 and \$matrix[4][2][2] == 1 and \$matrix[4][4][0] == 1 and \$matrix[4][4][1] == 1 and \$matrix[4][4][2] == 1 and \$matrix[4][5][0] == 1 and \$matrix[4][5][1] == 1 and \$matrix[4][5][2] == 1 and \$matrix[4][6][0] == 1 and \$matrix[4][6][1] == 1 and \$matrix[4][6][2] == 1) {
print "it worked";
}

<stdin>;
``````

edit note: If the way I'm approaching it is the best (doubt it), is there at least a way to make the if condition readable (not 36 compares on a single line)?

I suggest that you build an array of references to all the matrix elements in the subset. Then you can both set and test them in simple `for` loops

Here my array of references is called `@cells`. I've also used the `all` function from `List::Util`, which allows all the tests to be made in a single call, and will short-circuit as soon as any test fails

``````use strict;
use warnings 'all';

use List::Util 'all';

my @matrix;
my @cells;

# Initialise the matrix to all zeroes

for my \$i (0 .. 6) {
for my \$j (0 .. 6) {
for my \$k  (0 .. 2) {
\$matrix[\$i][\$j][\$k] = 0;
}
}
}

# Build an array of references to a subset of the cells
#
for my \$i ( 0 .. 2, 4 .. 6 ) {
push @cells, \\$matrix[\$i][4][\$_] for 0 .. 2;
}

for my \$j ( 0 .. 2, 4 .. 6 ) {
push @cells, \\$matrix[4][\$j][\$_] for 0 .. 2;
}

\$\$_ = 1 for @cells; # Set all the cells in the subset to 1

# Test that all cells in the subset are == 1
#
if ( all { \$\$_ == 1 } @cells ) {
print "It worked\n";
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download