Re: Arrays
by dragonchild (Archbishop) on Dec 08, 2001 at 00:42 UTC
|
Use an intermediate hash, like thus:
my %intermediateHash;
$intermediateHash{$_}++ for (@array1, @array2);
my @array3 = keys %intermediateHash;
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement. | [reply] [d/l] |
Re: Arrays
by runrig (Abbot) on Dec 08, 2001 at 00:50 UTC
|
Yet another (non-iterative) variation on the same (hash) theme: my @union = do { my %hash; @hash{@array1,@array2}=(); keys %hash };
| [reply] [d/l] |
|
|
Hey, that's very cool! This is starting to look like
a golf match. Let me use your method to remove the
foreach() loop from my solution:
my %hash = ();
@hash{ @array1, @array2 } = ();
@array3 = keys %hash;
I say once again: This is very cool!
Rob
| [reply] [d/l] |
|
|
@array3 = keys %{{ map {$_ =>1} @array1, @array2 }};
- danboo
| [reply] [d/l] |
|
|
|
|
|
|
|
|
Let me explain this (I've noticed that non-iterative
solutions are often odd-looking because they have no
cognate in the non-perl world):
my %hash = ();
This just creates a new, empty, associative array.
@hash{ @array1, @array2 } = ();
In this single line, the associative array has effectively
removed the duplicates from @array1 and @array2 for free.
This is a list assignment; that is, this single line
assigns into multiple keys. Just as $hash{$foo} = 0
creates a string key from $foo in the hash %hash,
so @hash{ @array } creates a bunch of keys, whose
members are named in @array, in the hash %hash. Also,
since two arrays mashed together form one big array--
that is, (@a1,@a2,@a3) becomes one flat array-- so then
the assignment @hash{ @array1, @array2 } creates string
keys out of each element in the arrays for %hash.
Since we know that keys are by nature unique, the
hashtable has removed the duplicates for us, for free!
So, now all there is left to do is extract the keys
from the hashtable:
@array3 = keys %hash;
...and we're done.
Rob | [reply] [d/l] [select] |
|
|
Let's establish some ground rules.
Provide a function that takes two arrayrefs, combines them and returns an array containing all the elements in the previous two arrays, bu no duplicates.
As I don't know them, you can't use commandline opts. *grins*
my @arr1 = (1, 2, 3, 4, 5);
my @arr2 = (4, 5, 6, 7, 8);
my @arr3 = f(\@arr1, \@arr2);
sub f {
#234567890#234567890#234567890
@h{map{@$_}@_}=1;keys%h
}
23 characters, and I know I can do better.
Update: 22 chars
@h{map@$_,@_}=1;keys%h
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement. | [reply] [d/l] [select] |
|
|
Re: Arrays
by joealba (Hermit) on Dec 08, 2001 at 00:43 UTC
|
my @array1 = (1, 2, 3);
my @array2 = (3, 4, 5);
my %union = ();
map { $union{$_}++ } (@array1, @array2);
my @array3 = keys %union;
Update: dragonchild is right. map is slower than a for loop. Use his code above, but you should still learn the wonderful world of map!
Update2:I like this one by danboo the best:
@array3 = keys %{{ map {$_ =>1} @array1, @array2 }};
It uses map in a non-void context, does a simple assignment operation instead of the addition/auto-vivify, and is still quite readable. Am I wrong? Is there a more optimized solution? | [reply] [d/l] [select] |
|
|
Just to nitpick - using map in a void context is generally considered poor style. It's also slower than the corresponding for loop. (And, almost always, less characters, closer to English, and uses "less complex" syntax.) *shrugs*
------ We are the carpenters and bricklayers of the Information Age. Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.
| [reply] |
|
|
Yeah, well, map pays me a monthly fee to use it everywhere possible. It's a whole marketing campaign. Soon you'll see got map? stickers on ThinkGeek.com and banner ads on PerlMonks and Slashdot - "First map!".
Sorry.. :) I'm just a map fan.
| [reply] [d/l] [select] |
|
|
|
|
Ah, you used map(). I'm going to have to learn that
function and start using it.
Rob
| [reply] |
Re: Arrays
by mpeppler (Vicar) on Dec 08, 2001 at 00:48 UTC
|
You could use something like this:
my @a1 = qw(one two three);
my @a2 = qw(one five four);
my %h = map { $_ => 1 } (@a1, @a2);
my @r = keys(%h);
print "@r\n";
This uses the map operator to create a hash, and then we
extract the keys from this hash to an array.
There are no doubt other ways to do this - but this one's
fairly straightforward.
Michael | [reply] [d/l] |
Re: Arrays
by rje (Deacon) on Dec 08, 2001 at 00:45 UTC
|
You could use a hashtable:
my %hashOfAllElements = ();
foreach $element (@array1, @array2)
{
$hashOfAllElements{ $element }++;
}
my @array3 = keys %hashOfAllElements;
I think that might do what you want.
Rob | [reply] [d/l] |
Re: Comparing Two Arrays
by davorg (Chancellor) on Dec 10, 2001 at 14:02 UTC
|
The problem with all the hash-based solutions is that
they lose the ordering of the arrays. If the order is
important, then try this:
foreach (@array1, @array2) {
push(@array3, $_) unless $seen{$_}++;
}
--
<http://www.dave.org.uk>
"The first rule of Perl club is you do not talk about
Perl club." -- Chip Salzenberg
| [reply] [d/l] |
| A reply falls below the community's threshold of quality. You may see it by logging in. |
| A reply falls below the community's threshold of quality. You may see it by logging in. |