chandantul has asked for the wisdom of the Perl Monks concerning the following question:

Hello Team, I have below data structure and i would like to create hash of arrays of hashes

use strict; use warnings; my %hash my @array1; my @array2; my @array3; -DATA- @array1 @array2 @array3 900000001 Network1 Login 900000002 Network1 2019-11-07T20:31:10.000Z 900000002 Network1 2021-02-19T13:47:25.000Z 900000002 Network1 2021-03-10T13:58:50.000Z 900000003 No Network1 NOT Registered 900000004 Network1 Login 900000005 Network1 Login 900000006 Network1 Login2 900000007 Network1 2021-03-10T17:11:24.000Z 900000007 Network1 2021-02-18T08:34:58.000Z 900000007 Network1 2021-01-25T17:19:44.000Z 500000008 Network1 2021-03-10T17:11:24.000Z 500000008 Network2 Not Used 500000008 Network1 2021-03-11T17:12:42.000Z 500000008 Network3 Not Used 400000008 Network1 2021-01-25T17:19:36.000Z @hash{@array1} = @array2; #This Works @{$hash{@array1}{@array2}}=[@array3];#This did not work

Replies are listed 'Best First'.
Re: How i can create hash of arrays of hashes from my 3 arrays?
by 1nickt (Canon) on Mar 13, 2021 at 15:27 UTC

    Your data structure is very odd. Why are there timestamps and strings mixed in the third column?

    It appears from your many questions that you are XYing your way through a task to parse a log for logins? Why don't you pose a question concerning your overall task, as your approach is surely not the right one.


    The way forward always starts with a minimal test.
Re: How i can create hash of arrays of hashes from my 3 arrays?
by tybalt89 (Monsignor) on Mar 13, 2021 at 11:53 UTC

    Just a guess...

    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11129561 use warnings; my %hash; while( <DATA> ) { my ($one, $two, $three) = split /\s{2,}|\n/; $hash{$one}{$two}{$three}++; } for my $value ( values %hash ) { $_ = [ sort keys %$_ ] for values %$value; } use Data::Dump 'dd'; dd \%hash; __DATA__ 900000001 Network1 Login 900000002 Network1 2019-11-07T20:31:10.000Z 900000002 Network1 2021-02-19T13:47:25.000Z 900000002 Network1 2021-03-10T13:58:50.000Z 900000003 No Network1 NOT Registered 900000004 Network1 Login 900000005 Network1 Login 900000006 Network1 Login2 900000007 Network1 2021-03-10T17:11:24.000Z 900000007 Network1 2021-02-18T08:34:58.000Z 900000007 Network1 2021-01-25T17:19:44.000Z 500000008 Network1 2021-03-10T17:11:24.000Z 500000008 Network2 Not Used 500000008 Network1 2021-03-11T17:12:42.000Z 500000008 Network3 Not Used 400000008 Network1 2021-01-25T17:19:36.000Z

    Outputs:

    { 400000008 => { Network1 => ["2021-01-25T17:19:36.000Z"] }, 500000008 => { Network1 => ["2021-03-10T17:11:24.000Z", "2021-03-11T +17:12:42.000Z"], Network2 => ["Not Used"], Network3 => ["Not Used"], }, 900000001 => { Network1 => ["Login"] }, 900000002 => { Network1 => [ "2019-11-07T20:31:10.000Z", "2021-02-19T13:47:25.000Z", "2021-03-10T13:58:50.000Z", ], }, 900000003 => { "No Network1" => ["NOT Registered"] }, 900000004 => { Network1 => ["Login"] }, 900000005 => { Network1 => ["Login"] }, 900000006 => { Network1 => ["Login2"] }, 900000007 => { Network1 => [ "2021-01-25T17:19:44.000Z", "2021-02-18T08:34:58.000Z", "2021-03-10T17:11:24.000Z", ], }, }
Re: How i can create hash of arrays of hashes from my 3 arrays?
by jcb (Parson) on Mar 14, 2021 at 03:10 UTC
Re: How i can create hash of arrays of hashes from my 3 arrays?
by BillKSmith (Monsignor) on Mar 13, 2021 at 11:43 UTC
    #$hash{$array1[$_]}{$array2[$_]} = $array3[$_] for (0..$#array1); push @{$hash{$array1[$_]}{$array2[$_]}}, $array3[$_] for (0..$#array1 +);

    UPDATE: Create hash-of-hash-of-arrays as hinted in OP code. This still does not agree with the title of the thread. Add output of updated code.

    OUTPUT: $VAR1 = { '400000008' => { 'Network1' => [ '2021-01-25T17:19:36.000Z' ] }, '500000008' => { 'Network2' => [ 'Not Used' ], 'Network1' => [ '2021-03-10T17:11:24.000Z', '2021-03-11T17:12:42.000Z' ], 'Network3' => [ 'Not Used' ] }, '900000001' => { 'Network1' => [ 'Login' ] }, '900000003' => { 'No Network1' => [ ' NOT Registered' ] }, '900000005' => { 'Network1' => [ 'Login' ] }, '900000007' => { 'Network1' => [ '2021-03-10T17:11:24.000Z', '2021-02-18T08:34:58.000Z', '2021-01-25T17:19:44.000Z' ] }, '900000002' => { 'Network1' => [ '2019-11-07T20:31:10.000Z', '2021-02-19T13:47:25.000Z', '2021-03-10T13:58:50.000Z' ] }, '900000004' => { 'Network1' => [ 'Login' ] }, '900000006' => { 'Network1' => [ 'Login2' ] } };
    Bill

      Thanks Bill This really helps but i will need to compare an array with User id details and then print the corrosponding Network details with recent login information and the counts the users attempts per Network . If user not logged in to a respective network then will use "Not Used" is that possible for you to help? I have included my effort on this function

      @array4 900000001 900000002 900000007 900000009 900000010 900000011 900000012 500000008
      foreach my $id (sort keys %hash) { foreach my $network(keys %{ $hash{$id} }) { foreach (0..$#array4) { if (exists $hash{$array4}{$network}) { print $hash5{$array4}; } else { print "Not Loggedin"; } } } }
        Your new specification makes little or no sense. I think you want to print the hash data for the users specified in @array4. Here is my attempt at that.
        foreach my $id (@array4) { print "User $id\n"; if (!exists $hash{$id}) { print " not logged in\n\n"; next; } foreach my $net (keys %{$hash{$id}}) { print " $net\n"; local $" = "\n "; print " @{$hash{$id}{$net}}\n"; } print "\n"; }
        OUTPUT: User 900000001 Network1 Login User 900000002 Network1 2019-11-07T20:31:10.000Z 2021-02-19T13:47:25.000Z 2021-03-10T13:58:50.000Z User 900000007 Network1 2021-03-10T17:11:24.000Z 2021-02-18T08:34:58.000Z 2021-01-25T17:19:44.000Z User 900000009 not logged in User 900000010 not logged in User 900000011 not logged in User 900000012 not logged in User 500000008 Network1 2021-03-10T17:11:24.000Z 2021-03-11T17:12:42.000Z Network2 Not Used Network3 Not Used
        Bill