The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> Perl Programming
|
Newbie question
Discuss Newbie question in the Perl Programming forum on Dev Shed. Newbie question Perl Programming forum discussing coding in Perl, utilizing Perl modules, and other Perl-related topics. Perl, the Practical Extraction and Reporting Language, is the choice for many for parsing textual information.
|
|
 |
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

March 19th, 2013, 11:01 AM
|
|
Registered User
|
|
Join Date: Mar 2013
Posts: 3
Time spent in forums: 46 m 49 sec
Reputation Power: 0
|
|
|
Newbie question
Here's what I'm trying to do...
Code:
my $input = "A=1;B=2;C=3;D=4";
my @array = split(';', $input);
At this point, in any other language, I'd lean toward creating a multidimensional array from those key=value pairs, but I don't think I can do that in perl. Here's where I'm stuck:
Code:
foreach(@array){
@stuff = split('=', $_);
# this is where I'm stuck
}
Assuming that $input isn't empty which it can be, I can reference $stuff[0] and $stuff[1] for the key/value pairs. How can I stuff those into a list so that later on I can iterate through them in a loop? I tried $x[$stuff[0]] = $stuff[1], but no go.
It'd be nice if I could understand it as well, but I'll settle for an esoteric oneliner too.
thanks,
will
|

March 19th, 2013, 11:13 AM
|
|
|
In this case you'll want to use a hash, which is an unordered list of key/value pairs.
Code:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %hash;
my $input = "A=1;B=2;C=3;D=4";
my @pairs = split /;/, $input;
foreach my $pair (@pairs) {
my ($key, $value) = split /=/, $pair;
$hash{$key} = $value;
}
print Dumper \%hash;
output:
c:\testing> example.pl
Code:
$VAR1 = {
'A' => '1',
'D' => '4',
'C' => '3',
'B' => '2'
};
|

March 19th, 2013, 02:59 PM
|
|
Registered User
|
|
Join Date: Mar 2013
Posts: 3
Time spent in forums: 46 m 49 sec
Reputation Power: 0
|
|
|
Awesome! Thanks. Any idea why/how the hash elements (not sure if that's the right term) are reordered?
|

March 19th, 2013, 03:13 PM
|
|
|
Hashes are unordered lists.
There is no guarantee that they will be stored in the same order as they are added. However, you can sort them as you loop over the pairs, or you can use a module such as Tie::IxHash to preserve the order in which the hash elements were added. It uses an array behind the scenes to maintain that order.
|

March 19th, 2013, 04:17 PM
|
|
Registered User
|
|
Join Date: Oct 2006
Posts: 13
Time spent in forums: 5 h 3 m 44 sec
Reputation Power: 0
|
|
If you don't want to use the dumper or tie-type modules, you can do something like this:
Code:
#!/usr/bin/perl
use strict;
use warnings;
#use Data::Dumper;
my %hash;
my $input = "A=1;B=2;C=3;D=4";
my @pairs = split /;/, $input;
#foreach my $pair (@pairs) {
# my ($key, $value) = split /=/, $pair;
# $hash{$key} = $value;
#}
#print Dumper \%hash;
while (<@pairs>)
{
my ($key,$value) = split /=/;
print "$key => $value\n";
}
Output is:
Code:
A => 1
B => 2
C => 3
D => 4
|

March 19th, 2013, 04:31 PM
|
|
|
That doesn't meet the OP's requirement of storing the key/value pairs for later retrieval. Unless you plan on needlessly parsing the @pairs array multiple times.
You could sort the hash after it's built
Code:
#!/usr/bin/perl
use strict;
use warnings;
my %hash;
my $input = "A=1;B=2;C=3;D=4";
my @pairs = split /;/, $input;
foreach my $pair (@pairs) {
my ($key, $value) = split /=/, $pair;
$hash{$key} = $value;
}
foreach my $key (sort keys %hash) {
print "$key => $hash{$key}\n";
}
Last edited by FishMonger : March 19th, 2013 at 04:39 PM.
Reason: Added code snippet
|

March 19th, 2013, 04:48 PM
|
|
|
If you want, that first foreach loop could be reduced to one simple line.
Code:
my %hash = map {split /=/} @pairs;
You reduce the code even more.
Code:
my $input = "A=1;B=2;C=3;D=4";
my %hash = map {split /=/} split /;/, $input;
or
Code:
my %hash = split /[;=]/, $input;
Last edited by FishMonger : March 19th, 2013 at 04:53 PM.
|

March 19th, 2013, 05:15 PM
|
|
|
|
Before I saw your last message, Fishmonger, I was just going to suggest two codes snippets using the map function almost exactly identical to your two first code snippets, but I was taken by surprise when looking at the last one, which I did not think of and which, I must, say, is pretty clever.
|

March 19th, 2013, 05:29 PM
|
|
Registered User
|
|
Join Date: Oct 2006
Posts: 13
Time spent in forums: 5 h 3 m 44 sec
Reputation Power: 0
|
|
You're the man, Fishmonger!
This is your world, I'm just a squirrel trying to find a nut!
Quote: | Originally Posted by FishMonger That doesn't meet the OP's requirement of storing the key/value pairs for later retrieval. Unless you plan on needlessly parsing the @pairs array multiple times.
You could sort the hash after it's built
Code:
#!/usr/bin/perl
use strict;
use warnings;
my %hash;
my $input = "A=1;B=2;C=3;D=4";
my @pairs = split /;/, $input;
foreach my $pair (@pairs) {
my ($key, $value) = split /=/, $pair;
$hash{$key} = $value;
}
foreach my $key (sort keys %hash) {
print "$key => $hash{$key}\n";
}
|
|

March 19th, 2013, 06:24 PM
|
|
|
Quote: | Originally Posted by Laurent_R Before I saw your last message, Fishmonger, I was just going to suggest two codes snippets using the map function almost exactly identical to your two first code snippets, but I was taken by surprise when looking at the last one, which I did not think of and which, I must, say, is pretty clever. |
It may be clever, but it's not really what I'd do in production code. I included it more for completeness.
There are times where it's better to be more verbose than clever.
|

March 20th, 2013, 02:26 AM
|
|
|
Quote: | Originally Posted by FishMonger It may be clever, but it's not really what I'd do in production code. I included it more for completeness.
There are times where it's better to be more verbose than clever. |
I fully agree, and I would not do that either on real code, but this kind of things can still be quite useful for oneliners or quick tests, possibly even prototypes.
|

March 21st, 2013, 11:30 AM
|
|
Registered User
|
|
Join Date: Mar 2013
Posts: 3
Time spent in forums: 46 m 49 sec
Reputation Power: 0
|
|
I guess a hash is sort of like an associative array in other languages which is what I was after. There really isn't a need for sorting or other ordering techniques. I was just curious how that worked since FishMonger's original code sample did not have random output at all -- it was identical ordering every time I ran it. Good stuff though.
Since you guys are so willing to share though, I've noticed that when working with individual hash keys you can reference them with or without quotes. Is there a difference between $hash{key} and $hash{'key'}?
|

March 21st, 2013, 01:56 PM
|
|
|
|
Yes, the keys don't come in random order, but in what seems to be random order. Whether you use the keys, the values or the each function, it will be each time the same order, which is in fact dependent on the way the keys and values are stored internally by Perl. And yes, a hash is one form of associative array.
As for the use of quotes, Perl "stringifies" the keys, i.e. transforms them into strings, which is why quotes are not necessary. So that using quotes or not usually does not make a difference.
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|