Re: Joining Arrays?
by Lawliet (Curate) on Dec 20, 2008 at 21:40 UTC
|
Well, without indentation your code is difficult to read. Try wrapping it in <c></c> tags and format it to be readable by those unfamiliar with it. From a quick glance there are many errors (such as putting a \n after the semi-colon. Using warnings will catch that.)
That being said, try (actually, don't try it -- just get inspiration from it :P)
#!/usr/bin/perl
use warnings;
use strict;
my @final; # Joined lines will be in here
open(URLS, '<', 'urls.txt') or die $!; # I can never remember if < is
+read
chomp(my @urls = <URLS>); # Every line of URLS is a different element
+in @urls
close URLS;
open(CODES, '<', 'data.txt') or die $!;
chomp(my @codes = <CODES>);
close CODES;
foreach my $url (@urls) { # For every element (line) in @urls,
foreach my $code (@codes) { # and for every element in @codes,
push @final, $url$code; # append the two and push it into @fin
+al
}
}
The first three lines should be in all your Perl programs. Using warnings will catch a lot of stupid mistakes you will make and using strictures will keep you from making a lot of stupid mistakes. I think the rest of the code is self explanatory.
Updated with more comments.
Update 2: Ikegami reminded me (thanks ikegami :D) that you must chomp() each element of the arrays before you push it into @final to remove the newline at the end. I'll update my code to show this soon. Done (with inspiration from kyle :P).
And you didn't even know bears could type.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
open(URLS, '<', 'urls.txt')
| |
| |
+----<-------+
from the file into the handle
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
Re: Joining Arrays?
by kyle (Abbot) on Dec 20, 2008 at 21:55 UTC
|
open my $url_fh, '<', 'urls.txt'
or die "Can't read 'urls.txt': $!";
chomp( my @urls = <$url_fh> );
close $url_fh or die "close() failed: $!";
open my $code_fh, '<', 'data.txt'
or die "Can't read 'data.txt': $!";
chomp( my @codes = <$code_fh> );
close $code_fh or die "close() failed: $!";
my @joined = map {
my $url = $_;
map { $url . $_ } @codes
} @urls;
Note that this actually creates an array for the results, while a foreach solution won't. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
There's something about nested maps that strikes me as unsavory. Sure, there's nothing syntactically wrong with it, but then there's nothing syntactically wrong with a sentence like "The cat the dog the man hit bit died."
In the case of nested maps, keeping track of what each $_ is holding involves an extra cognitive load. It's simply that it takes the reader a fair bit longer than normal to figure out the intent, and for that reason, I'd prefer to avoid it.
| [reply] [Watch: Dir/Any] |
|
# this doesn't work
my @joined
= map my $url { map my $code { $url . $code } @codes } @urls;
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
...nothing syntactically wrong with a sentence like "The cat the dog the man hit bit died."
Ah. Fluent reverse Polish. Or is it Yoda egg-nog on (too much) ?
I've tried to parse this... putting the brackets back in I get: died(the cat bit (the dog hit the man)) -- I'm assuming: (a) that each 'the' is part of the name of each object/subject; (b) that 'died' is a unary (intransitive); and (c) that 'bit' and 'hit' are binary operations (transitive).
So much for syntax... semantics-wise, assuming that the 'hit' and 'bit' operators return the object modified by the operation inflicted upon it by the subject...
...no wonder the man died. What on earth had he done to upset both the cat and the dog ? And what did the dog hit him with ?
Of course, being reverse polish the operators may themselves be reverse -- so the cat gets it because the man hit the dog ? What kind of twisted world is this ?
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
use v6;
my @urls = ('http://www.something.com/blah.aspx?code=',
'http://www.somethingelse.com/stuff.aspx?thing=');
my @ids = ('375035304','564564774','346464646');
my @combined = (@urls X @ids).map: {$^a ~ $^b};
.say for @combined;
Which outputs the following on Rakudo already:
http://www.something.com/blah.aspx?code=375035304
http://www.something.com/blah.aspx?code=564564774
http://www.something.com/blah.aspx?code=346464646
http://www.somethingelse.com/stuff.aspx?thing=375035304
http://www.somethingelse.com/stuff.aspx?thing=564564774
http://www.somethingelse.com/stuff.aspx?thing=346464646
The $^a and $^b in the map block tell it to take two elements at a time, while the X in the parenthesis tells it to cross join the two arrays. Very very handy for this kind of thing.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Such cross-like operations are common enough that there is also a cross meta-operator in Perl 6 to trick an ordinary binary operator into doing it. So instead of saying:
my @combined = (@urls X @ids).map: {$^a ~ $^b};
you can just say
my @combined = @urls X~ @ids;
That is, just put X in front of the ordinary operator to make it a cross operator.
Update: changed old X~X form to new X~ form. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
Interesting. But, unfortunately I am using perl 5.8. Where can I read about the new arrivals in perl 6 version?
| [reply] [Watch: Dir/Any] |
|