my @products = (
(name => "samsung s6" , price => "600"),
(name => "samsung s7" , price => "700"));
# for @products -> $x { say $x{"name"} ~ ": USD" ~ $x{"price"} };
# Desired output:
#
# samsung s6: USD600
# samsung s7: USD700
# Real output: An error:
#
# "Type List does not support associative indexing."
Run Code Online (Sandbox Code Playgroud)
我还想使用该.kv
方法进行迭代, $key
并且$val
像这样:
for @products -> $x.kv -> $key,$val { say $x{$key} ~ " " ~ $x{$val} };
# That gives a "Malformed parameter" error
Run Code Online (Sandbox Code Playgroud)
我查阅了 Raku 文档,但文档中没有提到这个特殊情况。怎么做?欢迎使用替代方法或对代码进行即兴创作。
使您的数据结构正确始终很重要。在这种情况下,他们感觉不对,但我想您被迫使用该格式。无论如何,我会这样解决:
for @products.map( { |(.[0].value, .[1].value) } ) -> $name, $price {
Run Code Online (Sandbox Code Playgroud)
换句话说:将带有对的列表映射到|
仅包含对值的Slip(前缀),并将其一次输入$name
和$price
两个元素。也许更好的可读性是:
for @products.map( { (.[0].value, .[1].value).Slip } ) -> $name, $price {
Run Code Online (Sandbox Code Playgroud)
对于给定的数据,您可以使用此子签名:
for @products -> @ ( :$name, :$price ) {
say "$name: USD$price"
}
Run Code Online (Sandbox Code Playgroud)
所以这需要一个未命名的 listy 参数@
。
然后它通过说它包含两个命名值来阐述这一点。
(这是有效的,因为您将它们作为 Pair 对象。)
真的,你所拥有的非常接近工作,你所要做的就是强制使用哈希。
for @products -> $x { say $x.hash{"name"} ~ ": USD" ~ $x.hash{"price"} }
for @products -> Hash() $x { say $x{"name"} ~ ": USD" ~ $x{"price"} }
Run Code Online (Sandbox Code Playgroud)
就个人而言,如果我要使用这些数据做很多工作,我会为它创建一个生态系统。
class Product {
has $.name;
has $.price;
our sub from-JSON-list ( @ (:$name, :$price) --> ::?CLASS ) {
::?CLASS.new( :$name, :$price )
}
method gist ( --> Str ) { "$.name: USD$.price" }
}
@products .= map: &Product::from-JSON-list;
.say for @products;
Run Code Online (Sandbox Code Playgroud)
如果你不喜欢&
你可以为 sub 创建一个常量别名。
…
constant from-JSON-list =
our sub from-JSON-list ( @ (:$name, :$price) ) {
::?CLASS.new( :$name, :$price )
}
…
@products .= map: Product::from-JSON-list;
Run Code Online (Sandbox Code Playgroud)