Forum Moderators: coopster & phranque

Message Too Old, No Replies

unique Array of Arrays

         

ktsirig

10:13 am on Jan 27, 2006 (gmt 0)

10+ Year Member



Hi all!
I have an array of arrays that i want to make unique. That is, I have:
@AoA=(["1","15"], ["2","5"], ["3","4"], ["3","5"], ["3","8"], ["3","5"], ["4","6"], ["4","5"])
and I want to remove array element ["3","5"] which is seen twice if you notice.
Is that possible? I am confused with this!

simon2263

12:55 pm on Jan 27, 2006 (gmt 0)

10+ Year Member



Try the following code. I can't claim any credit for this - it's really a slightly amended version (for arrays fo arrays) of something I found here: [stonehenge.com...]

Simon

-- code follows:

@AoA=(["1","15"], ["2","5"], ["3","4"], ["3","5"], ["3","8"], ["3","5"], ["4","6"], ["4","5"]) ;

# print out original array
foreach $a (@AoA) {
print "[";
foreach $v (@{$a}) {
print $v,",";
}
print "],";
}
print "\n";

# now remove duplicates - see web page for explanation
%temp = ();
@list = grep ++$temp{join(",",@{$_})} < 2, @AoA;

# now print again to see amended list
foreach $a (@list) {
print "[";
foreach $v (@{$a}) {
print $v,",";
}
print "],";

ktsirig

2:05 pm on Jan 27, 2006 (gmt 0)

10+ Year Member



Excellent post Simon, I think it works just fine (I did a small test on my data)!
The link is not working but your code was just perfect..

Pardon my silly question, but I am relatively new to Perl and even constructing the AoA was a pretty difficult task for me...

What is meant by :

@list = grep ++$temp{join(",",@{$_})} < 2, @AoA;

I have only understood the 'map' function Perl has, but I can't really understand what is going on and I wouldn't like to have a code that I can't explain...
If you find any time, pls be so kind and write 1-2 words for me...
Thanx a lot again!

simon2263

3:46 pm on Jan 27, 2006 (gmt 0)

10+ Year Member



Hi,

I don't know why the link doesn't work - it is redirected via a redirection CGI on webmaster which might be the cause - but if you type it in at the address bar, it works.

The key line of code is:

@list = grep ++$temp{join(",",@{$_})} < 2, @AoA;

grep is a built-in function that selects/rejects element from an array based on a true/false expression. Hence the second argument is the array we want to select from.

The first argument to grep is the true/false expression. As grep is looking through an array, it puts each element in turn into the special variable $_ (this pops up in lots of places in Perl). So the first argument to grep in this code examines $_ to see if the list element should be selected/rejected.

This selection/rejection is done using a hash data structure, in which the keys are the list elements, and the values are the number of times they are seen. So we turn the nested array into a string using the join function, and use it as a key into the temp hash - the value is a count of how many times we have seen this element. The expression is completed by asking if we have seen this element (or hash key) less than twice. If so, then grep accepts it; if no, we reject it.

Hope that's a bit clearer.

Simon

ktsirig

11:18 am on Jan 28, 2006 (gmt 0)

10+ Year Member



Yep, got it now...
Thanks a lot for your time...
Will check out the link as well!