Loading ...
Sorry, an error occurred while loading the content.

array of a hash

Expand Messages
  • carol white
    Hi, I build a hash and then, I  create an array of this hash and want to modify the value of one key of the hash. Although I assign the array to the built
    Message 1 of 16 , May 26 4:05 PM
    • 0 Attachment
      Hi,

      I build a hash and then, I  create an array of this hash and want to modify the value of one key of the hash. Although I assign the array to
      the built hash, it just gets the first key and value:

      perl test.pl
      1
      +1 u 1
      CD 0 AB 0

      and if I pass the reference of the hash, the hash gets modified
      perl test.pl
      2
      +1 u 0 1
      CD 0 AB 1

      What's wrong? see the attached program

      Thanks

      carol
      --------------------------------------------
      #!/usr/bin/perl

      sub parseFiles{
         %curr={};
         @currArr=();

          push @currArr,'+1';
          push @currArr,'u';
          push @currArr,\%currHash; # push @currArr,%currHash; in the first case

          $curr{"my"}=[@currArr];

          $curr{"my"}->[2]{"AB"}++;

          print scalar(keys %{$curr{"my"}->[2]}), "\n";

          print  $curr{"my"}->[0], " ", $curr{"my"}->[1], " ";

          foreach (keys %{$curr{"my"}->[2]}){
                  print $curr{"my"}->[2]{$_}, " ";
          }
          print "\n";
          foreach (keys %currHash){
                  print $_, " ", $currHash{$_}, " ";
          }
          print "\n";
      }
       
      sub storeHash{
              $currHash{"AB"}=$currHash{"CD"}= 0;
      }

      sub main{
          storeHash();
          parseFiles();
      }

      main();

       
    • Dave Anderson
      ... OK, without getting too far into your code, which isn t that clear, take this line. $curr{ my }- [2]{ AB }++; You ve dereferenced the @curr array, that s
      Message 2 of 16 , May 27 12:34 AM
      • 0 Attachment

        On 27/05/2014 00:05, carol white wht_crl@... [perl-beginner] wrote:
         
           %curr={};
           @currArr=();

            push @currArr,'+1';
            push @currArr,'u';
            push @currArr,\%currHash; # push @currArr,%currHash; in the first case

            $curr{"my"}=[@currArr];

            $curr{"my"}->[2]{"AB"}++;


        OK, without getting too far into your code, which isn't that clear, take this line.

          $curr{"my"}->[2]{"AB"}++;

        You've dereferenced the @curr array, that's fine, but element 2 contains a reference to a hash, not the hash itself (you pushed \%currHash) so perhaps you need to deference that too. To dereference the hash (and make things a bit clearer) you'd need something like

          $curr{"my"}->[2]->{"AB"}++;

        I haven't checked this but maybe that's the problem. (and you may need to clarify the above line further using curly brackets)

        regards
        Dave
      • carol white
        Hi, No it didn t change any thing. At any rate, what bothers is that if I reference to the hash (push @currArr, %currHash;), I assign the whole hash to the
        Message 3 of 16 , May 27 12:54 AM
        • 0 Attachment
          Hi,
          No it didn't change any thing. At any rate, what bothers is that if I reference to the hash (push @currArr,\%currHash;), I assign the whole hash to the array but the hash gets modified which is not desired and if I don't assign to the reference of the hash (push @currArr,%currHash;), just the first key and value are assigned to the array whereas I want to assign the whole hash.

          Without going to my code, in general, how it possible to assign a hash to an array which seems to be easy? Note that the array itself is a hash of array

          here is the structure

          hash - array (first and second elements, character, 3rd element, hash)

          Look forward to your feedback,


          On Tuesday, May 27, 2014 9:37 AM, "Dave Anderson dave@... [perl-beginner]" <perl-beginner@yahoogroups.com> wrote:


           

          On 27/05/2014 00:05, carol white wht_crl@... [perl-beginner] wrote:
           
             %curr={};
             @currArr=();

              push @currArr,'+1';
              push @currArr,'u';
              push @currArr,\%currHash; # push @currArr,%currHash; in the first case

              $curr{"my"}=[@currArr];

              $curr{"my"}->[2]{"AB"}++;


          OK, without getting too far into your code, which isn't that clear, take this line.

            $curr{"my"}->[2]{"AB"}++;

          You've dereferenced the @curr array, that's fine, but element 2 contains a reference to a hash, not the hash itself (you pushed \%currHash) so perhaps you need to deference that too. To dereference the hash (and make things a bit clearer) you'd need something like

            $curr{"my"}->[2]->{"AB"}++;

          I haven't checked this but maybe that's the problem. (and you may need to clarify the above line further using curly brackets)

          regards
          Dave


        • Dave Anderson
          ... Oh, I should have noticed this earlier. The above line creates a new array (with same elements as @currArr) and returns a reference to it. You didn t want
          Message 4 of 16 , May 27 1:36 AM
          • 0 Attachment

                $curr{"my"}=[@currArr];


            Oh, I should have noticed this earlier. The above line creates a new array (with same elements as @currArr) and returns a reference to it. You didn't want to copy the array?

            Just get a reference to the array.

            $curr{"my"} = \@currArr;


            regards
            Dave
            --
            web: www.marlinbrighton.com
          • carol white
            This doesn t solve the problem that the hash gets modified by being referenced. The problem is that how to assign the hash to the array without getting
            Message 5 of 16 , May 27 1:48 AM
            • 0 Attachment
              This doesn't solve the problem that the hash gets modified by being referenced. The problem is that how to assign the hash to the array without getting modified and have all its keys and values.

              Cheers,



              On Tuesday, May 27, 2014 10:36 AM, "Dave Anderson dave@... [perl-beginner]" <perl-beginner@yahoogroups.com> wrote:


               

                  $curr{"my"}=[@currArr];


              Oh, I should have noticed this earlier. The above line creates a new array (with same elements as @currArr) and returns a reference to it. You didn't want to copy the array?

              Just get a reference to the array.

              $curr{"my"} = \@currArr;


              regards
              Dave
              --
              web: www.marlinbrighton.com


            • Dave Anderson
              No, the hash doesn t get modified by being referenced. Here s some simple code to demonstrate my %hash1; my @arr1; my %hash2; $hash1{a} = hash element 1 ;
              Message 6 of 16 , May 27 2:17 AM
              • 0 Attachment
                No, the hash doesn't get modified by being referenced. Here's some simple code to demonstrate

                my %hash1;
                my @arr1;
                my %hash2;

                $hash1{a} = "hash element 1";
                $hash1{b} = "hash element 2";

                $arr1[0] = "arr element 0";
                $arr1[1] = "arr element 1";
                $arr1[2] = \%hash1;

                $hash2{my} = \@arr1;

                print $hash2{my} ->[2]->{a}, "\n";
                print $hash2{my} ->[2]->{b}, "\n";

                output:
                hash element 1
                hash element 2



                On 27/05/2014 09:48, carol white wht_crl@... [perl-beginner] wrote:
                 
                This doesn't solve the problem that the hash gets modified by being referenced. The problem is that how to assign the hash to the array without getting modified and have all its keys and values.

                Cheers,


                regards
                Dave
              • carol white
                try to print the hash1 and you will see that its values get changed. you can also run my program and see the output Thanks, On Tuesday, May 27, 2014 11:18 AM,
                Message 7 of 16 , May 27 2:23 AM
                • 0 Attachment
                  try to print the hash1 and you will see that its values get changed. you can also run my program and see the output

                  Thanks,



                  On Tuesday, May 27, 2014 11:18 AM, "Dave Anderson dave@... [perl-beginner]" <perl-beginner@yahoogroups.com> wrote:


                   
                  No, the hash doesn't get modified by being referenced. Here's some simple code to demonstrate

                  my %hash1;
                  my @arr1;
                  my %hash2;

                  $hash1{a} = "hash element 1";
                  $hash1{b} = "hash element 2";

                  $arr1[0] = "arr element 0";
                  $arr1[1] = "arr element 1";
                  $arr1[2] = \%hash1;

                  $hash2{my} = \@arr1;

                  print $hash2{my} ->[2]->{a}, "\n";
                  print $hash2{my} ->[2]->{b}, "\n";

                  output:
                  hash element 1
                  hash element 2



                  On 27/05/2014 09:48, carol white wht_crl@... [perl-beginner] wrote:
                   
                  This doesn't solve the problem that the hash gets modified by being referenced. The problem is that how to assign the hash to the array without getting modified and have all its keys and values.

                  Cheers,


                  regards
                  Dave


                • Dave Anderson
                  That s what those last two lines print out - the hash1. You can also print it out with a foreach using hash1 directly - the results are the same - hash1
                  Message 8 of 16 , May 27 2:48 AM
                  • 0 Attachment
                    That's what those last two lines print out - the hash1. You can also
                    print it out with a foreach using hash1 directly - the results are the
                    same - hash1 contains exactly what was put in it.

                    By the way, the hash gets modified in your example because you modify it
                    in this line

                    $curr{"my"}->[2]{"AB"}++;

                    The ++ increments the value of your AB hash element, which is why the
                    output is 0 1 rather than 0 0

                    regards
                    Dave
                  • carol white
                    print hash1 after $hash2{my} = @arr1; not before. I want to change the value of %curr not %currHash. How to change the value of 3rd element of $curr{key}
                    Message 9 of 16 , May 27 3:34 AM
                    • 0 Attachment
                      print hash1 after
                      $hash2{my} = \@arr1;

                      not before.

                      I want to change the value of %curr not %currHash. How to change the value of 3rd element of $curr{key} without changing %currHash? My goal is to initialize the 3rd element of $curr{key} by affecting its value to %currHash and to change the value of  $curr{key} later but not %currHash.

                      Cheers,


                      On Tuesday, May 27, 2014 11:48 AM, "Dave Anderson dave@... [perl-beginner]" <perl-beginner@yahoogroups.com> wrote:


                       
                      That's what those last two lines print out - the hash1. You can also
                      print it out with a foreach using hash1 directly - the results are the
                      same - hash1 contains exactly what was put in it.

                      By the way, the hash gets modified in your example because you modify it
                      in this line

                      $curr{"my"}->[2]{"AB"}++;

                      The ++ increments the value of your AB hash element, which is why the
                      output is 0 1 rather than 0 0

                      regards
                      Dave


                    • Dave Anderson
                      OK, you assign $curr{key} = @arr; # @arr contains a ref to %currHash and you want to change the third element of $curr{key} (i.e. @arr) so you change it
                      Message 10 of 16 , May 27 4:12 AM
                      • 0 Attachment
                        OK, you assign

                        $curr{key} = \@arr;  #  @arr contains a ref to %currHash

                        and you want to change the third element of $curr{key} (i.e. @arr)

                        so you change it

                        either $arr[2] = "new value";

                        or

                        $curr{key}->[2] = "new value";

                        Neither of those statements will affect $currHash.



                        On 27/05/2014 11:34, carol white wht_crl@... [perl-beginner] wrote:
                         
                        print hash1 after
                        $hash2{my} = \@arr1;

                        not before.

                        I want to change the value of %curr not %currHash. How to change the value of 3rd element of $curr{key} without changing %currHash? My goal is to initialize the 3rd element of $curr{key} by affecting its value to %currHash and to change the value of  $curr{key} later but not %currHash.

                        Cheers,
                        regards
                        Dave
                      • carol white
                        Doesn t work as I get the following output curr AB 1 currhash CD  AB   here is the adapted program #!/usr/bin/perl sub parseFiles{     @currArr=();  
                        Message 11 of 16 , May 27 4:30 AM
                        • 0 Attachment
                          Doesn't work as I get the following output

                          curr
                          AB 1
                          currhash
                          CD  AB  

                          here is the adapted program
                          #!/usr/bin/perl

                          sub parseFiles{
                              @currArr=();
                           

                              push @currArr,'+1';
                              push @currArr,'u';
                              push @currArr,%currHash; # push @currArr,%currHash; in the first case

                              $curr{"my"}=\@currArr;

                              $curr{"my"}->[2]{"AB"}++;

                              #print scalar(keys %{$curr{"my"}->[2]}), "\n";

                              #print  $curr{"my"}->[0], " ", $curr{"my"}->[1], "\n";

                          print "curr\n";

                              foreach (keys %{$curr{"my"}->[2]}){
                                      print  $_, " ", $curr{"my"}->[2]{$_}, " ";
                              }
                              print "\n";

                          print "currhash\n";

                              foreach (keys %currHash){
                                      print $_, " ", $tmp{$_}, " ";
                              }
                              print "\n";
                          }
                           
                          sub storeHash{
                           

                                  $currHash{"AB"}=$currHash{"CD"}= 0;
                             
                          }

                          sub main{

                              storeHash();
                              parseFiles();
                          }

                          main();

                           


                          On Tuesday, May 27, 2014 1:12 PM, "Dave Anderson dave@... [perl-beginner]" <perl-beginner@yahoogroups.com> wrote:


                           
                          OK, you assign

                          $curr{key} = \@arr;  #  @arr contains a ref to %currHash

                          and you want to change the third element of $curr{key} (i.e. @arr)

                          so you change it

                          either $arr[2] = "new value";

                          or

                          $curr{key}->[2] = "new value";

                          Neither of those statements will affect $currHash.



                          On 27/05/2014 11:34, carol white wht_crl@... [perl-beginner] wrote:
                           
                          print hash1 after
                          $hash2{my} = \@arr1;

                          not before.

                          I want to change the value of %curr not %currHash. How to change the value of 3rd element of $curr{key} without changing %currHash? My goal is to initialize the 3rd element of $curr{key} by affecting its value to %currHash and to change the value of  $curr{key} later but not %currHash.

                          Cheers,
                          regards
                          Dave


                        • Dave Anderson
                          ... You ve removed the pushing a reference %currHash ... You still have this line which modifies $currHash ... $tmp doesn t exist.
                          Message 12 of 16 , May 27 4:54 AM
                          • 0 Attachment

                            On 27/05/2014 12:30, carol white wht_crl@... [perl-beginner] wrote:
                             
                                push @currArr,%currHash; # push @currArr,%currHash; in the first case

                            You've removed the pushing a reference  \%currHash


                                $curr{"my"}->[2]{"AB"}++;

                            You still have this line which modifies $currHash

                                foreach (keys %currHash){
                                        print $_, " ", $tmp{$_}, " ";   

                            $tmp doesn't exist.
                          • carol white
                            you said it s enough to ref to @arr and if I leave ref to hash, the hash gets modified. $curr{ my }- [2]{ AB }++; is on purpose as I explained many times that
                            Message 13 of 16 , May 27 5:08 AM
                            • 0 Attachment
                              you said it's enough to ref to @arr and if I leave ref to hash, the hash gets modified.

                              $curr{"my"}->[2]{"AB"}++; is on purpose as I explained many times that i want to change the value of $curr but not the hash

                              $tmp can be replaced by currHash. it was a mistake and after replacement, i still get

                              curr
                              CD 0 AB 1
                              currhash
                              CD 0 AB 1
                              How you change my program to get

                              curr
                              CD 0 AB 1
                              currhash
                              CD 0 AB 0
                              ????




                              On Tuesday, May 27, 2014 1:54 PM, "Dave Anderson dave@... [perl-beginner]" <perl-beginner@yahoogroups.com> wrote:


                               

                              On 27/05/2014 12:30, carol white wht_crl@... [perl-beginner] wrote:
                               
                                  push @currArr,%currHash; # push @currArr,%currHash; in the first case

                              You've removed the pushing a reference  \%currHash


                                  $curr{"my"}->[2]{"AB"}++;

                              You still have this line which modifies $currHash

                                  foreach (keys %currHash){
                                          print $_, " ", $tmp{$_}, " ";   

                              $tmp doesn't exist.


                            • Dave Anderson
                              And I explained many times that that line changes the hash, not $curr. You can t have value 1 going through $curr, and value 0 going through currHash, because
                              Message 14 of 16 , May 27 6:48 AM
                              • 0 Attachment
                                And I explained many times that that line changes the hash, not $curr.

                                You can't have value 1 going through $curr, and value 0 going through currHash, because if you've passed a ref to $currHash, then both ways of referring to this value are referencing the same object. That's the point of references.

                                If you want to have different values then you have to create a new hash which is a copy of $currHash and put that into $curr. I don't have time to write it right now.

                                On 27/05/2014 13:08, carol white wht_crl@... [perl-beginner] wrote:
                                 
                                you said it's enough to ref to @arr and if I leave ref to hash, the hash gets modified.

                                $curr{"my"}->[2]{"AB"}++; is on purpose as I explained many times that i want to change the value of $curr but not the hash

                                $tmp can be replaced by currHash. it was a mistake and after replacement, i still get

                                curr
                                CD 0 AB 1
                                currhash
                                CD 0 AB 1
                                How you change my program to get

                                curr
                                CD 0 AB 1
                                currhash
                                CD 0 AB 0
                                ????




                                On Tuesday, May 27, 2014 1:54 PM, "Dave Anderson dave@... [perl-beginner]" <perl-beginner@yahoogroups.com> wrote:


                                 

                                On 27/05/2014 12:30, carol white wht_crl@... [perl-beginner] wrote:
                                 
                                    push @currArr,%currHash; # push @currArr,%currHash; in the first case

                                You've removed the pushing a reference  \%currHash


                                    $curr{"my"}->[2]{"AB"}++;

                                You still have this line which modifies $currHash

                                    foreach (keys %currHash){
                                            print $_, " ", $tmp{$_}, " ";   

                                $tmp doesn't exist.



                                --
                                Dave Anderson
                                Marlin Brighton
                                Independent IT Consultancy
                                Mob: 07710 537 909
                                email: dave@...
                                web: www.marlinbrighton.com
                              • Bilashi Sahu
                                Hi I have this code. It does not change value in curhash, but changes in last hash in my case myhash Hope it helps my %curhash = (     AB = 0,    
                                Message 15 of 16 , May 28 7:34 PM
                                • 0 Attachment


                                  Hi
                                  I have this code.
                                  It does not change value in curhash, but changes in last hash in my case "myhash"
                                  Hope it helps
                                  my %curhash = (
                                      'AB' => 0,
                                      'CD' => 0
                                  );

                                  my @curArray = ();
                                  push(@curArray, '+1');
                                  push(@curArray, 'u');

                                  push(@curArray, \%curhash);

                                  my $lasthash = {};
                                  my %myhash = (
                                   'my' => \@curArray
                                  );
                                  $myhash->{'my'}[2]{'AB'}++;
                                  print "Value in myhash\n";
                                  print $myhash{'my'}[0]. "\n";
                                  print $myhash{'my'}[1]. "\n";
                                  print $myhash->{'my'}[2]{'AB'}. "\n";
                                  print $myhash{'my'}[2]{'CD'}. "\n";  

                                  print "value in %curhash";
                                  foreach $k(keys %curhash) {

                                     print "each value in curhash: " . $curhash{$k} ."\n";
                                  }



                                  Result:
                                  =======

                                  perl arrayofhash.pl 

                                  Value in myhash
                                  +1
                                  u
                                  1
                                  0
                                  value in %curhash
                                  each value in curhash: 0
                                  each value in curhash: 0


                                  From: "Dave Anderson dave@... [perl-beginner]" <perl-beginner@yahoogroups.com>
                                  To: perl-beginner@yahoogroups.com
                                  Sent: Tuesday, May 27, 2014 6:48 AM
                                  Subject: Re: [PBML] array of a hash

                                   
                                  And I explained many times that that line changes the hash, not $curr.

                                  You can't have value 1 going through $curr, and value 0 going through currHash, because if you've passed a ref to $currHash, then both ways of referring to this value are referencing the same object. That's the point of references.

                                  If you want to have different values then you have to create a new hash which is a copy of $currHash and put that into $curr. I don't have time to write it right now.

                                  On 27/05/2014 13:08, carol white wht_crl@... [perl-beginner] wrote:
                                   
                                  you said it's enough to ref to @arr and if I leave ref to hash, the hash gets modified.

                                  $curr{"my"}->[2]{"AB"}++; is on purpose as I explained many times that i want to change the value of $curr but not the hash

                                  $tmp can be replaced by currHash. it was a mistake and after replacement, i still get

                                  curr
                                  CD 0 AB 1
                                  currhash
                                  CD 0 AB 1
                                  How you change my program to get

                                  curr
                                  CD 0 AB 1
                                  currhash
                                  CD 0 AB 0
                                  ????




                                  On Tuesday, May 27, 2014 1:54 PM, "Dave Anderson dave@... [perl-beginner]" <perl-beginner@yahoogroups.com> wrote:


                                   

                                  On 27/05/2014 12:30, carol white wht_crl@... [perl-beginner] wrote:
                                   
                                      push @currArr,%currHash; # push @currArr,%currHash; in the first case

                                  You've removed the pushing a reference  \%currHash


                                      $curr{"my"}->[2]{"AB"}++;

                                  You still have this line which modifies $currHash

                                      foreach (keys %currHash){
                                              print $_, " ", $tmp{$_}, " ";   

                                  $tmp doesn't exist.



                                  --
                                  Dave Anderson
                                  Marlin Brighton
                                  Independent IT Consultancy
                                  Mob: 07710 537 909
                                  email: dave@...
                                  web: www.marlinbrighton.com


                                • merlynstonehengecom
                                  ... Bilashi my %myhash = ( Bilashi   my = @curArray Bilashi ); Bilashi $myhash- { my }[2]{ AB }++; Two separate things. use strict would have caught
                                  Message 16 of 16 , May 28 8:12 PM
                                  • 0 Attachment
                                    >>>>> "Bilashi" == Bilashi Sahu bilashi sahu@yahoo com [perl-beginner] <perl-beginner@yahoogroups.com> writes:

                                    Bilashi> my %myhash = (
                                    Bilashi>  'my' => \@curArray
                                    Bilashi> );
                                    Bilashi> $myhash->{'my'}[2]{'AB'}++;

                                    Two separate things. "use strict" would have caught that.

                                    --
                                    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
                                    <merlyn@...> <URL:http://www.stonehenge.com/merlyn/>
                                    Perl/Unix consulting, Technical writing, Comedy, etc. etc.
                                    Still trying to think of something clever for the fourth line of this .sig
                                  Your message has been successfully submitted and would be delivered to recipients shortly.