CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
Delete an array of hash references

 



PapaGeek
User

Jun 21, 2014, 4:04 PM

Post #1 of 6 (3126 views)
Delete an array of hash references Can't Post

I need to constantly destroy and reload an array of hashes from a database table.

Attached is a stripped down test version of what I need to do that does not require the database.

The actual output of the code is:


Code
acc 6  ABC6  30 
acc 7 ABC7 35
acc 8 ABC8 40
acc 9 ABC9 45
delete the array here so I can refill it
acc 6 ABC6 30
acc 7 ABC7 35
acc 8 ABC8 40
acc 9 ABC9 45
acc 1 ABC1 5
acc 2 ABC2 10


The commented code does not compile, if it did and it did its job properly, the second printout of the array would only include the lines for ABC1 and ABC2, not 6, 7, 8, 9, 1, 2

Can someone tell me the proper coding to completely delete an array of hash references so I can re-fill it again with push statements?


Code
use Modern::Perl '2013'; 

main();

sub main
{
my @investmentsHashArray;

for (my $idx = 6 ; $idx <= 9 ; $idx++ )
{
my %dataHash;
$dataHash{"account"} = "acc $idx";
$dataHash{"ticker"} = "ABC$idx";
$dataHash{"amount"} = $idx * 5;
push (@investmentsHashArray, \%dataHash);
}
foreach (@investmentsHashArray)
{
my $hashRef = $_;
say "$$hashRef{'account'} $$hashRef{'ticker'} $$hashRef{'amount'}";
}

# this is the code that does not compile
# I want to completely delete te array of hashes so I cna rebuild it.
say "delete the array here so I can refill it";
# foreach (@investmentsHashArray)
# {
# my $hashRef = $_;
# foreach $key (keys $hashRef)
# {
# delete $$hashRef{$key};
# }
# }

# I want the push in this code to add to the emptied array
for (my $idx = 1 ; $idx <= 2 ; $idx++ )
{
my %dataHash;
$dataHash{"account"} = "acc $idx";
$dataHash{"ticker"} = "ABC$idx";
$dataHash{"amount"} = $idx * 5;
push (@investmentsHashArray, \%dataHash);
}

# this code should only print out the two hashes created above
foreach (@investmentsHashArray)
{
my $hashRef = $_;
say "$$hashRef{'account'} $$hashRef{'ticker'} $$hashRef{'amount'}";
}
}



BillKSmith
Veteran

Jun 21, 2014, 9:28 PM

Post #2 of 6 (2903 views)
Re: [PapaGeek] Delete an array of hash references [In reply to] Can't Post

You can remove the contents of any array by assiginging an empty list.


Code
@investmentsHashArray = ();


In this case, another approach is to add braces around each major section of code so the array goes out of scope at the end of the block.

I have a number of issues with your style.
  • Do not use C-style for loops

  • Push a reference to an anonymous hash into your array.

  • Use a hash slice to simplify your output

  • You do not need a 'main' subroutine in perl






  • Code
    use 5.10.1; 
    use strict;
    use warnings;
    my @investmentsHashArray;

    for my $idx (6..9)
    {
    push @investmentsHashArray, {
    account => "acc $idx",
    ticker => "ABC$idx",
    amount => $idx * 5,
    };
    }

    foreach my $hashRef (@investmentsHashArray)
    {
    $" = ' ';
    say "@{$hashRef}{'account', 'ticker', 'amount'}";
    }

    say "delete the array here so I can refill it";
    @investmentsHashArray = ();


    # I want the push in this code to add to the emptied array
    for my $idx (1..2)
    {
    push @investmentsHashArray, {
    account => "acc $idx",
    ticker => "ABC$idx",
    amount => $idx * 5,
    };
    }

    # this code should only print out the two hashes created above
    foreach my $hashRef (@investmentsHashArray)
    {
    $" = ' ';
    say "@{$hashRef}{'account', 'ticker', 'amount'}";
    }

    Good Luck,
    Bill


    Laurent_R
    Veteran / Moderator

    Jun 22, 2014, 11:19 PM

    Post #3 of 6 (2547 views)
    Re: [PapaGeek] Delete an array of hash references [In reply to] Can't Post

    I would probably go for a scoping solution, using a block to give @investmentsHashArray proper scope, as this makes the intent of the developper very clear. If you create an array, delete it and recreate it to store new data, you might also ask yourself whether it would not make sense to use another variable with another variable name.

    I should add that I fully agree with Bill's coding style comments.


    FishMonger
    Veteran / Moderator

    Jun 23, 2014, 8:37 AM

    Post #4 of 6 (2521 views)
    Re: [PapaGeek] Delete an array of hash references [In reply to] Can't Post

    In addition to the given suggestions, I'd also suggest fixing your var names. TitleCaseVarNames are always harder to read. It's best practice to join the words with underscores and use lowercase.

    Code
    my @investments_hash_array;

    That var name implies that it's an AoHoA (Array of Hashes of Arrays), which it isn't.

    If you want the var name to describe the type of data structure then use the abbreviated form.

    Code
    @investments_AoH;


    I rarely use the structure definition in the var name because in most cases it just adds unnecessary line noise.

    Personally I don't like the $$hashRef{'key'} construct when de referencing a hash or array ref. I prefer the use arrow notation.
    $hash_ref->{'key'}
    $array_ref->[0]

    I thing it adds more clarity.


    (This post was edited by FishMonger on Jun 23, 2014, 8:38 AM)


    PapaGeek
    User

    Jun 23, 2014, 8:46 AM

    Post #5 of 6 (2514 views)
    Re: [FishMonger] Delete an array of hash references [In reply to] Can't Post

    Thanks FishMonger, I will make those changes. I've only been writing in Perl for less than a year, have to start thinking more Perlish!

    At least I've stopped calling it Pearl!


    Zhris
    Enthusiast

    Jun 23, 2014, 10:39 AM

    Post #6 of 6 (2445 views)
    Re: [PapaGeek] Delete an array of hash references [In reply to] Can't Post

    A shortened version of your code as it stands, although takes away the good learning experience of constructing hashes and arrays ;):


    Code
    range_to_row( 6, 9 ); 
    range_to_row( 1, 2 );

    sub range_to_row
    {
    printf "acc %s\tABC%s\t%s\n", $_, $_, $_*5 for ( shift // 1 .. shift // 1 );
    }


    Chris


    (This post was edited by Zhris on Jun 23, 2014, 10:43 AM)

     
     


    Search for (options) Powered by Gossamer Forum v.1.2.0

    Web Applications & Managed Hosting Powered by Gossamer Threads
    Visit our Mailing List Archives