lizmat and yet another Rakudo Weekly News hits the Net: rakudoweekly.blog/2025/01/13/2025-02-ditana/ 12:25
librasteve \o/ 16:49
ikarus13 I expect %data<key1> to return a List and if I write it as a single statement, it returns a list, but in a loop, where I want to loop over that list, the running variable is the whole list. Why is that. [0] > my %data = ( key1 => [ { a => 1, b => 2 }, { c => 3, d => 4 } ], key2 => [ { e => 5, f => 6 }, { g => 7, h => 8 } ] ); {key1 => [{a => 1, b => 2} {c => 3, d => 4}], key2 => [{e => 5, f => 6} {g 18:40
=> 7, h => 8}]} [1] > for %data<key1> -> $map { say $map } [{a => 1, b => 2} {c => 3, d => 4}] If I force it to List, I get the expected behaviour. [1] > for %data<key1>.List -> $map { say $map } {a => 1, b => 2} {c => 3, d => 4} Can somebody explain it to me, please?
lizmat elements in a hash are containerized 18:45
or itemized, if you will 18:46
this means they won't iterate
there are a number of ways around it
m: my %h = a => (1,2,3); .say for %h<a>; # does not iterate 18:47
camelia (1 2 3)
ikarus13 I have a hashmap of lists of hashmaps. I want to loop over an element of that hashmap. [0] > my %data = ( key1 => [ { a => 1, b => 2 }, { c => 3, d => 4 } ], key2 => [ { e => 5, f => 6 }, { g => 7, h => 8 } ] ); {key1 => [{a => 1, b => 2} {c => 3, d => 4}], key2 => [{e => 5, f => 6} {g => 7, h => 8}]} If I access an element of that hashmap, it returns the list/array. [1] > %data<key1> [{a => 1, b
=> 2} {c => 3, d => 4}] But if I want to loop over it, it the running variable swallows the whole list: [1] > for %data<key1> -> $map { say $map } [{a => 1, b => 2} {c => 3, d => 4}] If I put a .List at the end, it works as expected. [1] > for %data<key1>.List -> $map { say $map } {a => 1, b => 2} {c => 3, d => 4} Can someone please explain that to me?
lizmat m: my %h = a => (1,2,3); .say for %h<a><>; # iterates because of the decontainerization with <> as postfix
camelia 1
2
3
lizmat another way:
if you control how the hash is made
m: my %h; %h<a> := (1,2,3); .say for %h<a> 18:48
camelia 1
2
3
lizmat that works because binding to the key doesn't containerize
ikarus13 ah, interesting. Hashes containerize items and as such they are not iterable. Got it! 18:49
lizmat another way to decontainerize, is to turn the hash into a Map:
m: my %h = a => (1,2,3); .say for %h.Map<a>
camelia 1
2
3
lizmat but you probably want to do that once
m: my %h = a => (1,2,3); my %m := %h.Map; .say for %m<a> 18:50
camelia 1
2
3
lizmat the postfix <> method is probably the easiest to apply
ikarus13 Is there a disadvantage to treating it as a Map? 18:51
lizmat it needs to do a lot of work to turn the Hash into a Map
if you can create it as a Map, that would be best
m: my %m is Map = a => (1,2,3); .say for %m<a> 18:52
camelia 1
2
3
ikarus13 ok, thank you :)