3

I am trying to write code that confirms every row in 2 dimensional array has all unique values.

@x2 = uniq( @q2 ); produced array with 10 elements instead of 6; then $y2 = @x2; produced 1??

I don't understand why x2 is different than x1 and y2 is different than y1? I am expecting x2 with 5 elements and y2=5 (just like y1). How can I fix this?

#!/usr/bin/perl
use strict;
use warnings;

use Data::Dumper;
use List::MoreUtils qw(uniq);

my @q1 = (6,0,0,5,0,7,0,0,1,0);
my @x1 = uniq( @q1 );
my $y1 = @x1;
print "y1 = ",Dumper( $y1 );
print "x1 = ",Dumper( @x1 );
print "q1 = ",Dumper( @q1 );

print '====='."\n";

my @b = ();
push @{ $b[0] }, (0,8,0,0,0,9,3,5,6,7);
push @{ $b[1] }, (6,0,0,5,0,7,0,0,1,0);

my $r=1;
my @q2=$b[$r];
my @x2 = uniq( @q2 );
my $y2 = @x2;
print "y2 = ",Dumper( $y2 );
print "x2 = ",Dumper( @x2 );
print "q2 = ",Dumper( @q2 );
print "b[r]=",Dumper( $b[$r] );
3
  • 3
    my @q2= @{ $b[$r]} ; this Commented Aug 22, 2020 at 16:35
  • 1
    That @q2 in the shown code doesn't have 10 elements (?) -- you assign $b[1] to it, an array reference so a single scalar. So @x2 has the same, one element which is an array reference. Do as @Сухой27 says instead, @{$b[$r]}. Commented Aug 22, 2020 at 17:59
  • 1
    Tip: There's no point in assigning zero scalars (= ()) to a newly-created array (my @b). It's already empty. Commented Aug 22, 2020 at 19:49

1 Answer 1

3

Arrays can only contains scalars. This means they can't contain arrays, at least not directly. So we use references to arrays as array elements (since references are scalars).

Thanks to autovivification,

push @{ $b[0] }, (0,8,0,0,0,9,3,5,6,7);

is short for

push @{ $b[0] //= [] }, (0,8,0,0,0,9,3,5,6,7);

And [] returns a reference to a newly created array.

So when you do my @q2 = $b[$r];, you are assigning a single scalar to @q2 (the one created by the implicit []). To copy the elements of the array referenced by $b[$r], you can use

my @q2 = @{ $b[$r] };

As an aside, the following can be written better:

push @{ $b[0] }, (0,8,0,0,0,9,3,5,6,7);

Since $b[0] doesn't exist when this is executed, we can use

$b[0] = [0,8,0,0,0,9,3,5,6,7];

Finally, there's no reason to hardcode 0. We could use

push @b, [0,8,0,0,0,9,3,5,6,7];

So we get

my @b;  # Note the lack of a useless, noisy "= ()".
push @b, [0,8,0,0,0,9,3,5,6,7];
push @b, [6,0,0,5,0,7,0,0,1,0];

or

my @b = (
   [0,8,0,0,0,9,3,5,6,7],
   [6,0,0,5,0,7,0,0,1,0],
);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.