Re: I don't get map. How would I use map here?
by Zaxo (Archbishop) on Jun 18, 2004 at 20:15 UTC
|
The first can be written,
my %byFile = map { reverse split } <DATA>;
That relies on the data being reliable in format.
The second can be mapped, too, but I'd more likely write it either the way you have it, or else as while (my ($key, $val) = each %byFile) { . . . }. Here is a mapped version,
print map {"$_\t=>$byFile{$_}\n"} keys %byFile;
I'd favor the "while each" version because it is more sparing of memory, and the results are not likely needed elsewhere.
| [reply] [d/l] [select] |
Re: I don't get map. How would I use map here?
by NetWallah (Canon) on Jun 18, 2004 at 20:00 UTC
|
The key thing to understand is that map returns a list.
If you do not need a list returned, (which is the case in your example),use for.
Update:Style suggestion:
Your second loop is better written as
while (my ($k,$v) = each %byFile ) {
print "$k\t=>$v\n";
}
This is more idiomatic, uses less memory, and is faster than your loop.
Offense, like beauty, is in the eye of the beholder, and a fantasy.
By guaranteeing freedom of expression, the First Amendment also guarantees offense.
| [reply] [d/l] |
Re: I don't get map. How would I use map here?
by jeffa (Bishop) on Jun 18, 2004 at 21:12 UTC
|
| [reply] |
Re: I don't get map. How would I use map here?
by duff (Parson) on Jun 18, 2004 at 20:21 UTC
|
#!/usr/bin/perl
use strict;
print map { "$_->[1]\t=>$_->[0]\n" } map { [ split ] } <DATA>;
__DATA__
0 5713813
276k CVS_RES
264k Desktop
17k Documes
33k SEARCH
But the magic really isn't so much in the map as it is in the use of an anonymous array.
| [reply] [d/l] [select] |
Re: I don't get map. How would I use map here?
by Eimi Metamorphoumai (Deacon) on Jun 18, 2004 at 20:15 UTC
|
Personally, I wouldn't use map in either of those places. Definitely not in the second, since it would be evaluating it for side effects only. For the first you could use
%byFile = map {(split /\s+/)[1,0]} <DATA>;
with the proviso that it would remove anything already in %byFile. That is, it would take each element from DATA and translate it into two elements, creating a list of pairs to be treated as a hash. But I still don't think this is a great place for map, because it's not as easy to read (and quite a bit more confusing). | [reply] [d/l] |
Re: I don't get map. How would I use map here?
by Fletch (Bishop) on Jun 18, 2004 at 20:12 UTC
|
Use map to transform one list of values into a new list; use for to iterate over a list performing some operations. In both of your cases you're not really generating a new list. The first one could be done as my %byFile = map { chomp; split( /\s+/, $_, 2 ) } <DATA>, but I'd personally use the for instead. Considering your second loop is a single statement I'd probably write it as print "$_\t=>$byFile{$_}\n" for keys %byFile, but definately not using map.
| [reply] [d/l] [select] |
Re: I don't get map. How would I use map here?
by eric256 (Parson) on Jun 18, 2004 at 20:03 UTC
|
| [reply] [d/l] |
|
print map { "$_\t=>$byFile{$_}\n" } keys %byFile;
or
print "$_\t=>$byFile{$_}\n" for keys %byFile; # look Ma! no map! :-)
| [reply] [d/l] [select] |
Re: I don't get map. How would I use map here?
by pbeckingham (Parson) on Jun 18, 2004 at 20:55 UTC
|
while (<DATA>)
{
print "$2\t=>$1\n" if /^(.*?)\s+(.*?)$/;
}
__DATA__
0 5713813
276k CVS_RES
264k Desktop
17k Documes
33k SEARCH
Then I'd substitute the map for the for:
map {print "$2\t=>$1\n" if /^(.*?)\s+(.*?)$/} <DATA>;
__DATA__
0 5713813
276k CVS_RES
264k Desktop
17k Documes
33k SEARCH
As long as you are okay with there being a serious loss in readability, and it smacks of golf.
| [reply] [d/l] [select] |
Re: I don't get map. How would I use map here?
by Chady (Priest) on Jun 19, 2004 at 09:42 UTC
|
One OT but related note is the use of for to read from a filehandle.
I got bitten by that before.
for will create the list and iterate over it. This means that if <DATA> is a filehandle to a file containing 1Gb of data, for will attempt to create the 1Gb+ list, thus bringing your system to its knees.
The 'safer' way to do this would be to use a while instead of for because it doesn't create the list.
He who asks will be a fool for five minutes, but he who doesn't ask will remain a fool for life.
Chady | http://chady.net/
| [reply] [d/l] [select] |
Re: I don't get map. How would I use map here?
by ryantate (Friar) on Jun 18, 2004 at 21:53 UTC
|
Not sure if you're looking to replace both loops entirely or whether you need %byFile for other purposes ...
print map {join("\t=>", reverse split) . "\n"} <DATA>;
Update: replaced superflous foreach after print
| [reply] [d/l] [select] |
|
| [reply] [d/l] [select] |
|
Not without putting it in a different loop:
print join("\t=>", reverse split), "\n" while <DATA>;
We're not really tightening our belts, it just feels that way because we're getting fatter.
| [reply] [d/l] |