00:01
jaguart joined,
jaguart left
01:15
deadmarshal_ left
01:43
deadmarshal_ joined
09:02
dakkar joined
|
|||
lizmat | and yet another Rakudo Weekly News hits the Net: rakudoweekly.blog/2025/01/13/2025-02-ditana/ | 12:25 | |
librasteve | \o/ | 16:49 | |
17:39
dakkar left
|
|||
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 :) |