Great answers already. Brad's Hash()
coercion solution is so sweet!
But it felt like another answer was called for. No one directly discussed your impulse to go the key/value route using .kv
, and the error you got:
I would also like to iterate using the .kv
method ... "Malformed parameter"
.kv
isn't helpful because of the nature of your data
Your data is such that .kv
just isn't going to help you get where you need to go. (Which is why no one used it.)
Why not?
Here's your data:
(name => "samsung s6" , price => "600"),
(name => "samsung s7" , price => "700"),
...
Each element in @products
is a sub-list of two key/value pairs.
But all of the keys are useless!
What you really want to do is throw away the existing keys and then construct brand new pairs by treating the value of the first pair in each @products
element as a new key and the value of the second pair as the associated value.
So you end up with something like:
("samsung s6" => "600"),
("samsung s7" => "700"),
To do this you need to forget .kv
.
Instead you need to suitably combine something like a .value
routine with a .pairup
routine. And indeed that works:
.say for @products[*;*]».value.pairup
displays:
samsung s6 => 600
samsung s7 => 700
Let's break that down:
.say for @products[*;*]
displays:
name => samsung s6
price => 600
name => samsung s7
price => 700
For an explanation of what the [*;*]
is doing, see my answer to How do I “flatten” a list of lists?.
As already explained, the keys are useless. We want the value from each Pair
:
.say for @products[*;*]».value
displays:
samsung s6
600
samsung s7
700
A »
in this scenario is like an inner for
loop, or a map
. For example, I could have written:
.value.say for (do @$_ for @products[*;*])
But it's a lot easier to write just the one character »
. This gets rid of the extra parens, inner for
construct, and what not.
Finally we tack a .pairup
on the end to pair up odd and even elements of a list; each odd element becomes a key, and the following (even) element becomes the associated value. Job done.
About the error message
The error message includes an ⏏
. This is an "eject" symbol, pinpointing where the parser gave up:
------> for @products -> $x⏏.kv
The words "Malformed parameter" are calling out the .
in your code:
for @products -> $x.kv ...
The $x
has been parsed as a parameter, or at least the start of one. But then what's with the .
? It might be invoking a method call if it were part of an expression, but here you should be finishing up specifying the name of a parameter. So the parser bails.