counting number of uniques in a multidimensional array column

T

Ted Zlatanov

Here's a (very simple) function to give you the unique items from a
list you pass:

sub uniques
{
my %unique = ();
$unique{$_}++ foreach @_;
return keys %unique;
}

Now use it like this:

my @columnarray = ( [1,2,3], [1,2,3], [4,5,6], [7,8,9], );

foreach my $column (1 .. scalar @{$columnarray[0]})
{
print "Unique elements in column $column: ";
print join ', ',
uniques(map { $_->[$column-1] }
@columnarray
);
print "\n";
}

I formatted this to be easy to understand, and I tested it with the
data above under

use warnings;
use strict;

and it worked correctly. Please learn from the code posted above - it
shows many useful techniques.
Ted - this is excellent stuff - how exactly can I capture an example of
2 elements representing a duplicate in a variable from this code ???

If you want to remember duplicates (untested):

sub uniques
{
my %unique = ();
$unique{$_}++ foreach @_;
my @ukeys = keys %unique;
my @dkeys = grep { $unique{$_} > 1 } @ukeys;
return [\@ukeys, \@dkeys];
}

then later use it like this in the loop over @columnarray:

my $keys = uniques(map { $_->[$column-1] } @columnarray;

print "Unique elements in column $column: ";
print join ', ', @{$keys->[0]};

print "Duplicate elements in column $column: ";
print join ', ', @{$keys->[1]};

So this modifies uniques() to return two arrays, the list of unique
values and the list of unique values that appeared more than once,
inside a two-element array. The result is stored in $keys. The
original version just returned a list of unique values.

@{$keys->[0]} means "get the first element of the $keys array
reference, and since it's an array itself, convert it to a list
(dereference it)."

Note this is untested :)

Ted
 
J

Jack

Ted said:
Here's a (very simple) function to give you the unique items from a
list you pass:

sub uniques
{
my %unique = ();
$unique{$_}++ foreach @_;
return keys %unique;
}

Now use it like this:

my @columnarray = ( [1,2,3], [1,2,3], [4,5,6], [7,8,9], );

foreach my $column (1 .. scalar @{$columnarray[0]})
{
print "Unique elements in column $column: ";
print join ', ',
uniques(map { $_->[$column-1] }
@columnarray
);
print "\n";
}

I formatted this to be easy to understand, and I tested it with the
data above under

use warnings;
use strict;

and it worked correctly. Please learn from the code posted above - it
shows many useful techniques.
Ted - this is excellent stuff - how exactly can I capture an example of
2 elements representing a duplicate in a variable from this code ???

If you want to remember duplicates (untested):

sub uniques
{
my %unique = ();
$unique{$_}++ foreach @_;
my @ukeys = keys %unique;
my @dkeys = grep { $unique{$_} > 1 } @ukeys;
return [\@ukeys, \@dkeys];
}

then later use it like this in the loop over @columnarray:

my $keys = uniques(map { $_->[$column-1] } @columnarray;

print "Unique elements in column $column: ";
print join ', ', @{$keys->[0]};

print "Duplicate elements in column $column: ";
print join ', ', @{$keys->[1]};

So this modifies uniques() to return two arrays, the list of unique
values and the list of unique values that appeared more than once,
inside a two-element array. The result is stored in $keys. The
original version just returned a list of unique values.

@{$keys->[0]} means "get the first element of the $keys array
reference, and since it's an array itself, convert it to a list
(dereference it)."

Note this is untested :)

Ted

Hi Ted - great and thank you.. I tried the above and even with some
fiddling could not get it to work.. If you know of a way to just
capture and print out 1 example of a duplicate (not all), thats all I
am speaking of.

Thank you,
Jack
 
T

Ted Zlatanov

Hi Ted - great and thank you.. I tried the above and even with some
fiddling could not get it to work.. If you know of a way to just
capture and print out 1 example of a duplicate (not all), thats all I
am speaking of.

Can you please post:

1) an example of your data
2) an example of the output you expect
3) what you have tried so far (and why it doesn't work)

I've given you very complete answers (I think), and don't want to keep
answering the wrong questions...

Ted
 

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

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top