Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: Add new rows and data to array.

by johngg (Canon)
on Mar 19, 2020 at 19:56 UTC ( [id://11114485]=note: print w/replies, xml ) Need Help??


in reply to Add new rows and data to array.

Leaving aside the question of whether you would be better served by a RDBMS, the way you organise your data into a ref. to an array of hashes makes your life rather difficult. To first get an idea of your problem I edited your $data to break it over multiple lines so it was easier to read. It was then clear that a ref. to a hash keyed by "ID" containing sub-hashes keyed by "status" in turn containing sub-sub-hashes with the remaining key/value pairs would make data access and manipulation easier. The data can be remodelled using hash slices rather than having to faff around with each individual key/value pair. There is a useful table on the various ways of accessing data structures here.

The first part of the code transforms the data into the new form that is easier to manipulate. The second part adds the new keys for those IDs that have an "Extra" sub-hash. Finally we Dumpxs() the resultant data structure. The code:-

use strict; use warnings; use Data::Dumper; # Original $data edited to make it easier (for my old eyes) to read. # my $dataItems = [ { Ad1 => q{20 North Central St.}, status => q{Main}, City => q{NY}, zCode => q{0002}, name => q{John D}, ID => q{2222}, state => q{TO} }, { Ad1 => q{15 South Street}, status => q{Property}, City => q{NY}, zCode => q{0002}, name => q{John V}, ID => q{2222}, state => q{TO} }, { Ad1 => q{100 main St.}, status => q{Extra}, City => q{BO}, zCode => q{0007}, name => q{Tony Star}, ID => q{2222}, state => q{UA} }, { Ad1 => q{5540 Chelsea Avenue}, status => q{Cabin}, City => q{NE}, zCode => q{4562}, name => q{Carly Simon}, ID => q{2222}, state => q{TO} }, { Ad1 => q{12th Street}, status => q{Main}, City => q{NM}, zCode => q{2334}, name => q{Charles D}, ID => q{1111}, state => q{CA} }, { Ad1 => q{44 Dell St}, status => q{Extra}, City => q{MA}, zCode => q{9857}, name => q{Marie Doe}, ID => q{1111}, state => q{CA} }, { Ad1 => q{33 Dust Road}, status => q{Property}, City => q{ET}, zCode => q{3345}, name => q{Chapim Thor}, ID => q{1111}, state => q{CA} }, { Ad1 => q{01 Charles St}, status => q{Cabin}, City => q{CA}, zCode => q{2334}, name => q{Claud Odur}, ID => q{1111}, state => q{CA} }, { Ad1 => q{1AAAA}, status => q{Main}, City => q{AA}, zCode => q{TTTT}, name => q{AKAKAK}, ID => q{8888}, state => q{PP} }, { Ad1 => q{2AAAA}, status => q{Test}, City => q{BB}, zCode => q{WWWW}, name => q{BXBXBX}, ID => q{8888}, state => q{HH} }, { Ad1 => q{CCCCC}, status => q{Property}, City => q{ET}, zCode => q{3345}, name => q{Chapim Thor}, ID => q{8888}, state => q{CA} }, { Ad1 => q{DDDDD}, status => q{Cabin}, City => q{CA}, zCode => q{2334}, name => q{Claud Odur}, ID => q{8888}, state => q{CA} }, ]; # Re-arrange the reftoAoH $data into a reftoHoHoH $rhByID using hash # slices. # my $rhByID = {}; my @subKeys = qw{ Ad1 City zCode name state }; foreach my $rhItem ( @{ $dataItems } ) { @{ $rhByID->{ $rhItem->{ ID } }->{ $rhItem->{ status } } }{ @subKe +ys } = @{ $rhItem }{ @subKeys }; } # Now add in the new keys and associated values for those IDs that hav +e # a "Extra" sub-key, again using hash slices. I've included "state" in # case it had been omitted from the OP code by mistake. # my @newKeys = qw{ newAd1 newCity newZip newName newState }; foreach my $id ( keys %{ $rhByID } ) { next unless exists $rhByID->{ $id }->{ Extra }; @{ $rhByID->{ $id }->{ Main } }{ @newKeys } = @{ $rhByID->{ $id }->{ Extra } }{ @subKeys }; } # Dump the new data structure. # print Data::Dumper ->new( [ $rhByID ], [ qw{ rhByID } ] ) ->Sortkeys( 1 ) ->Indent( 1 ) ->Dumpxs();

The output:-

$rhByID = { '1111' => { 'Cabin' => { 'Ad1' => '01 Charles St', 'City' => 'CA', 'name' => 'Claud Odur', 'state' => 'CA', 'zCode' => '2334' }, 'Extra' => { 'Ad1' => '44 Dell St', 'City' => 'MA', 'name' => 'Marie Doe', 'state' => 'CA', 'zCode' => '9857' }, 'Main' => { 'Ad1' => '12th Street', 'City' => 'NM', 'name' => 'Charles D', 'newAd1' => '44 Dell St', 'newCity' => 'MA', 'newName' => 'Marie Doe', 'newState' => 'CA', 'newZip' => '9857', 'state' => 'CA', 'zCode' => '2334' }, 'Property' => { 'Ad1' => '33 Dust Road', 'City' => 'ET', 'name' => 'Chapim Thor', 'state' => 'CA', 'zCode' => '3345' } }, '2222' => { 'Cabin' => { 'Ad1' => '5540 Chelsea Avenue', 'City' => 'NE', 'name' => 'Carly Simon', 'state' => 'TO', 'zCode' => '4562' }, 'Extra' => { 'Ad1' => '100 main St.', 'City' => 'BO', 'name' => 'Tony Star', 'state' => 'UA', 'zCode' => '0007' }, 'Main' => { 'Ad1' => '20 North Central St.', 'City' => 'NY', 'name' => 'John D', 'newAd1' => '100 main St.', 'newCity' => 'BO', 'newName' => 'Tony Star', 'newState' => 'UA', 'newZip' => '0007', 'state' => 'TO', 'zCode' => '0002' }, 'Property' => { 'Ad1' => '15 South Street', 'City' => 'NY', 'name' => 'John V', 'state' => 'TO', 'zCode' => '0002' } }, '8888' => { 'Cabin' => { 'Ad1' => 'DDDDD', 'City' => 'CA', 'name' => 'Claud Odur', 'state' => 'CA', 'zCode' => '2334' }, 'Main' => { 'Ad1' => '1AAAA', 'City' => 'AA', 'name' => 'AKAKAK', 'state' => 'PP', 'zCode' => 'TTTT' }, 'Property' => { 'Ad1' => 'CCCCC', 'City' => 'ET', 'name' => 'Chapim Thor', 'state' => 'CA', 'zCode' => '3345' }, 'Test' => { 'Ad1' => '2AAAA', 'City' => 'BB', 'name' => 'BXBXBX', 'state' => 'HH', 'zCode' => 'WWWW' } } };

I don't know whether you are able to modify your data in this way but I really think it would make your life much easier.

Cheers,

JohnGG

Replies are listed 'Best First'.
Re^2: Add new rows and data to array.
by camtauxe (Sexton) on Mar 19, 2020 at 20:37 UTC

    I suppose without knowing exactly how the original poster intends to use the data, it's hard to say if this would be better, but might it be even easier to use a multidimensional hash in this case?

    Example:

    %data = ( "1111$;Cabin" => { 'Ad1' => '01 Charles St', 'City' => 'CA', 'name' => 'Claud Odur', 'state' => 'CA', 'zCode' => '2334' }, # ... # snip # ... "8888$;Test" => { 'Ad1' => '2AAAA', 'City' => 'BB', 'name' => 'BXBXBX', 'state' => 'HH', 'zCode' => 'WWWW' } ); # Now elements of the data can be accessed like this my $val = $data{'1111','Cabin'}->{'City'}; # Or, to get a slice of rows where status is 'Main', you could do this +: my @main = @data{grep /$;Main$/, keys %data}

    Edit: Added the line about accessing rows where status 'Main'

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11114485]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2024-03-28 08:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found