• Building hash of hashes?

    From Otto J. Makela@21:1/5 to All on Fri Aug 27 16:59:40 2021
    The following demo builds a counter (using a hash of hashes) into
    memory from the DATA section and then displays the result. However,
    I'm not terribly fond of the way I create the hashes in the hash.

    This demo of course is a simplification of my actual use case,
    where I ended up having three-layered hashes embedded with
    complex initialization.

    Does anyone have suggestions for a "neater" way to do this?

    ----

    #!/usr/bin/perl
    use strict;
    use warnings;

    # Collect DATA into hash of hashes
    my %data;
    while(<DATA>) {
    chomp;
    (my $a, my $b) = split(/\s+/,$_,2);
    if(defined $data{$a}) {
    $data{$a}{$b}++;
    } else {
    $data{$a} = { $b => 1 };
    }
    }

    # Print out collected data
    foreach my $a (sort keys %data) {
    print $a;
    foreach my $b (sort keys $data{$a}) {
    print "\t",$b,"\t",$data{$a}{$b},"\n";
    }
    }

    __DATA__
    yy cc
    xx aa
    yy aa
    yy bb
    xx cc
    zz cc
    yy bb
    xx bb
    yy aa

    --
    /* * * Otto J. Makela <om@iki.fi> * * * * * * * * * */
    /* Phone: +358 40 765 5772, ICBM: N 60 10' E 24 55' */
    /* Mail: Mechelininkatu 26 B 27, FI-00100 Helsinki */
    /* * * Computers Rule 01001111 01001011 * * * * * * */

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From AnonymousCoward@21:1/5 to All on Fri Aug 27 21:07:30 2021
    How about:

    #!/usr/bin/perl
    use strict;
    use warnings;

    # Collect DATA into hash of hashes
    my %data;
    while(my $l = <DATA>) {
    chomp $l;
    (my $a, my $b) = split(/\s+/,$l,2);
    $data{$a}{$b}++;
    }

    # Print out collected data
    while (my ($a, $d) = each %data) {
    print $a;
    print "\t$_\t@{[$d->{$_}]}\n" for (sort keys %$d);
    }


    __DATA__
    yy cc
    xx aa
    yy aa
    yy bb
    xx cc
    zz cc
    yy bb
    xx bb
    yy aa

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Otto J. Makela@21:1/5 to AnonymousCoward on Mon Aug 30 15:39:39 2021
    AnonymousCoward <anonymous@coward.com> wrote:

    How about:
    ...
    (my $a, my $b) = split(/\s+/,$l,2);
    $data{$a}{$b}++;

    Okay, this was actually what I felt was the ugliest bit:
    I wasn't aware that anonymous hashes would automatically
    get instantiated into the hash. Thus the convolutions I
    went to manually build them were quite unnecessary.

    I've learnt a new thing here, thank you!
    --
    /* * * Otto J. Makela <om@iki.fi> * * * * * * * * * */
    /* Phone: +358 40 765 5772, ICBM: N 60 10' E 24 55' */
    /* Mail: Mechelininkatu 26 B 27, FI-00100 Helsinki */
    /* * * Computers Rule 01001111 01001011 * * * * * * */

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From George Bouras@21:1/5 to All on Wed Sep 1 11:18:43 2021
    #!/bin/perl
    use strict;
    use warnings;

    # Collect DATA into hash of hashes
    my %data;
    while (<DATA>) {
    $data{$1}->{$2}++ if /^(\S+)\s+(.*?)\s*$/
    }

    use Data::Dumper; print Dumper \%data;

    __DATA__
    yy cc
    xx aa
    yy aa
    yy bb
    xx cc
    zz cc
    yy bb
    xx bb
    yy aa

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Randal L. Schwartz@21:1/5 to All on Thu Sep 2 17:56:49 2021
    "Otto" == Otto J Makela <om@iki.fi> writes:

    Otto> Okay, this was actually what I felt was the ugliest bit:
    Otto> I wasn't aware that anonymous hashes would automatically
    Otto> get instantiated into the hash. Thus the convolutions I
    Otto> went to manually build them were quite unnecessary.

    Yes, thanks to the loved/hated feature of autovivification.

    --
    Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/> Perl/Dart/Flutter consulting, Technical writing, Comedy, etc. etc.
    Still trying to think of something clever for the fourth line of this .sig

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Otto J. Makela@21:1/5 to George Bouras on Mon Sep 6 16:58:33 2021
    George Bouras <foo@example.com> wrote:

    $data{$1}->{$2}++ if /^(\S+)\s+(.*?)\s*$/

    This works just as well even without the explicitly written ->

    My actual use case was significantly more convoluted,
    with three levels of indirection, this was just a simplification.
    --
    /* * * Otto J. Makela <om@iki.fi> * * * * * * * * * */
    /* Phone: +358 40 765 5772, ICBM: N 60 10' E 24 55' */
    /* Mail: Mechelininkatu 26 B 27, FI-00100 Helsinki */
    /* * * Computers Rule 01001111 01001011 * * * * * * */

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From George Bouras@21:1/5 to All on Mon Sep 6 23:47:30 2021
    My actual use case was significantly more convoluted,
    with three levels of indirection, this was just a simplification.

    no problem if you want more help

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)