Thread: Newbie question

    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    3
    Rep 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
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,930
    Rep Power
    1225
    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'
            };

    Comments on this post

    • walvord agrees
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    3
    Rep Power
    0
    Awesome! Thanks. Any idea why/how the hash elements (not sure if that's the right term) are reordered?
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,930
    Rep Power
    1225
    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.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2006
    Posts
    13
    Rep 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
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,930
    Rep Power
    1225
    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
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,930
    Rep Power
    1225
    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;

    Comments on this post

    • Laurent_R agrees
    Last edited by FishMonger; March 19th, 2013 at 04:53 PM.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    830
    Rep Power
    496
    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.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2006
    Posts
    13
    Rep Power
    0
    You're the man, Fishmonger!
    This is your world, I'm just a squirrel trying to find a nut!






    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";
    }
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,930
    Rep Power
    1225
    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.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    830
    Rep Power
    496
    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.
  22. #12
  23. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    3
    Rep 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'}?
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2012
    Posts
    830
    Rep Power
    496
    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.

IMN logo majestic logo threadwatch logo seochat tools logo