Skip to content

Instantly share code, notes, and snippets.

@0racle
Last active January 20, 2021 06:24
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save 0racle/e074c2d6634458bf43a1c79a4030486c to your computer and use it in GitHub Desktop.
Nested

I was playing around with nesting data in hashes, and came up with... something.
Some kinda tree structure with JSON-Path like access.
Not sure what this might be useful for.

Raku and Perl implementations below...

Raku

use Data::Dump;

sub nest($hash, @path) is rw {
    my $ref = $hash;
    for @path.head(*-1) -> $key {
        $ref = $ref{$key} //= {}; 
    }   
    $ref{@path.tail};
}

my %t; 

nest(%t, < one two >)        = 'one.two';
nest(%t, < one three >)      = 'one.three';
nest(%t, < one four five >)  = 'one.four.five';
nest(%t, < two three four >) = 'two.three.four';

say Dump %t; 

OUTPUT

{
  one => {
    four  => {
      five => "one.four.five".Str,
    },
    three => "one.three".Str,
    two   => "one.two".Str,
  },
  two => {
    three => {
      four => "two.three.four".Str,
    },
  },
}

Perl 5

use v5.26;
use warnings;
use experimentals;
use List::AllUtils qw< head tail >;
use DDP;

sub nest :lvalue ($hash_ref, @path) {
    my $ref = $hash_ref;
    for my $key (head(-1, @path)) {
        $ref = $ref->{$key} //= {}; 
    }   
    $ref->{tail(1, @path)};
}

my $t = {}; 

nest($t, qw< one two >)        = 'one.two';
nest($t, qw< one three >)      = 'one.three';
nest($t, qw< one four five >)  = 'one.four.five';
nest($t, qw< two three four >) = 'two.three.four';

p $t; 

OUTPUT

\ {
    one   {
        four    {
            five   "one.four.five"
        },
        three   "one.three",
        two     "one.two"
    },
    two   {
        three   {
            four   "two.three.four"
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment