UpTide - 4 years ago 144

Perl Question

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)?

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

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**