访问成对列表数组中的值
Accessing the values in an array of lists of pairs
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."
我还想使用 .kv
方法以及 $key
和 $val
进行迭代,如下所示:
for @products -> $x.kv -> $key,$val { say $x{$key} ~ " " ~ $x{$val} };
# That gives a "Malformed parameter" error
我已经查阅了 Raku 文档,但文档中没有提到这种特殊情况。怎么做?
欢迎使用替代方法或即兴创作代码。
正确设置数据结构始终很重要。在这种情况下,他们感觉不对,但我猜你被迫使用那种格式。无论如何,我会这样解决:
for @products.map( { |(.[0].value, .[1].value) } ) -> $name, $price {
换句话说:将带有对的列表映射到仅包含对值的 Slip(前缀 |
),并将其输入 $name
和 $price
两个元素一个时间。也许更好的可读性是:
for @products.map( { (.[0].value, .[1].value).Slip } ) -> $name, $price {
由于 raku OO 是如此轻量级,您可以 使用 class 这是管理 non-uniform 数据结构的好方法:
class Product {
has $.name;
has $.price;
method gist { "$.name: USD$.price" }
}
my @products = (
Product.new(name => "samsung s6" , price => "600"),
Product.new(name => "samsung s6" , price => "600"),
);
.say for @products;
#samsung s6: USD600
#samsung s6: USD600
对于给出的数据,你可以使用这个sub-signature:
for @products -> @ ( :$name, :$price ) {
say "$name: USD$price"
}
所以这需要一个未命名的 listy 参数 @
。
然后它通过说它包含两个命名值来阐述这一点。
(这是有效的,因为您将它们作为 Pair 对象。)
真的,你所拥有的已经非常接近工作了,你所要做的就是强制哈希。
for @products -> $x { say $x.hash{"name"} ~ ": USD" ~ $x.hash{"price"} }
for @products -> Hash() $x { say $x{"name"} ~ ": USD" ~ $x{"price"} }
就我个人而言,如果我要对这些数据做大量工作,我会为它创建一个生态系统。
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;
如果您不喜欢 &
您可以为该子程序创建一个常量别名。
…
constant from-JSON-list =
our sub from-JSON-list ( @ (:$name, :$price) ) {
::?CLASS.new( :$name, :$price )
}
…
@products .= map: Product::from-JSON-list;
你得到这个错误的原因是你正在构造一个 List
of List
s of Pair
s 但把它当作 List
of [=15] =]es.
代码最简单的修复是更新数据结构以匹配您的处理方式:
my @products = (
{name => "samsung s6" , price => "600"},
{name => "samsung s7" , price => "700"}
);
本例中的 {}
被评估为 Hash
构造函数。我认为问题出在 Raku =>
是一个 Pair
构造函数而不是一个特殊的逗号。
正如其他人所建议的那样,轻量级对象也很有用,但我认为了解如何构建您认为您正在构建的东西是很好的。
已经有很好的答案了。 Brad 的 Hash()
强制解决方案太棒了!
但感觉需要另一个答案。没有人直接讨论你使用 .kv
走 key/value 路线的冲动,以及你得到的错误:
I would also like to iterate using the .kv
method ... "Malformed parameter"
由于数据的性质,.kv
没有帮助
您的数据 .kv
不会帮助您到达需要去的地方。 (这就是为什么没有人使用它的原因。)
为什么不呢?
这是您的数据:
(name => "samsung s6" , price => "600"),
(name => "samsung s7" , price => "700"),
...
@products
中的每个元素都是两个 key/value 对的 sub-list。
但是 所有 键 无用!
你真正想做的是扔掉现有的键,然后构建全新的对 通过将每个 @products
元素中第一对的 value 视为 new 键和 第二对的 value 作为关联的 value.
所以你最终会得到这样的结果:
("samsung s6" => "600"),
("samsung s7" => "700"),
为此,您需要忘记 .kv
。
相反,您需要适当地将 .value
例程与 .pairup
例程相结合。确实有效:
.say for @products[*;*]».value.pairup
显示:
samsung s6 => 600
samsung s7 => 700
让我们分解一下:
.say for @products[*;*]
显示:
name => samsung s6
price => 600
name => samsung s7
price => 700
有关 [*;*]
正在做什么的解释,请参阅 。
如前所述,这些键是无用的。我们想要每个 Pair
:
的 value
.say for @products[*;*]».value
显示:
samsung s6
600
samsung s7
700
A »
在这种情况下就像一个内部 for
循环,或 map
。例如,我可以这样写:
.value.say for (do @$_ for @products[*;*])
但是只写一个字»
要容易得多。这摆脱了额外的括号,内部 for
构造,以及什么不是。
最后我们在末尾添加一个 .pairup
来配对列表的奇数和偶数元素;每个 odd 元素成为一个键,后面的(偶数)元素成为关联值。工作完成。
关于错误信息
错误消息包含 ⏏
。这是一个“弹出”符号,指出解析器放弃的位置:
------> for @products -> $x⏏.kv
“格式错误的参数”一词在您的代码中调用了 .
:
for @products -> $x.kv ...
$x
已被解析为参数,或者至少是一个参数的开头。但是 .
是怎么回事?如果它是表达式的一部分,它可能会调用方法调用,但在这里您应该完成指定参数名称的操作。所以解析器保释。
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."
我还想使用 .kv
方法以及 $key
和 $val
进行迭代,如下所示:
for @products -> $x.kv -> $key,$val { say $x{$key} ~ " " ~ $x{$val} };
# That gives a "Malformed parameter" error
我已经查阅了 Raku 文档,但文档中没有提到这种特殊情况。怎么做? 欢迎使用替代方法或即兴创作代码。
正确设置数据结构始终很重要。在这种情况下,他们感觉不对,但我猜你被迫使用那种格式。无论如何,我会这样解决:
for @products.map( { |(.[0].value, .[1].value) } ) -> $name, $price {
换句话说:将带有对的列表映射到仅包含对值的 Slip(前缀 |
),并将其输入 $name
和 $price
两个元素一个时间。也许更好的可读性是:
for @products.map( { (.[0].value, .[1].value).Slip } ) -> $name, $price {
由于 raku OO 是如此轻量级,您可以 使用 class 这是管理 non-uniform 数据结构的好方法:
class Product {
has $.name;
has $.price;
method gist { "$.name: USD$.price" }
}
my @products = (
Product.new(name => "samsung s6" , price => "600"),
Product.new(name => "samsung s6" , price => "600"),
);
.say for @products;
#samsung s6: USD600
#samsung s6: USD600
对于给出的数据,你可以使用这个sub-signature:
for @products -> @ ( :$name, :$price ) {
say "$name: USD$price"
}
所以这需要一个未命名的 listy 参数 @
。
然后它通过说它包含两个命名值来阐述这一点。
(这是有效的,因为您将它们作为 Pair 对象。)
真的,你所拥有的已经非常接近工作了,你所要做的就是强制哈希。
for @products -> $x { say $x.hash{"name"} ~ ": USD" ~ $x.hash{"price"} }
for @products -> Hash() $x { say $x{"name"} ~ ": USD" ~ $x{"price"} }
就我个人而言,如果我要对这些数据做大量工作,我会为它创建一个生态系统。
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;
如果您不喜欢 &
您可以为该子程序创建一个常量别名。
…
constant from-JSON-list =
our sub from-JSON-list ( @ (:$name, :$price) ) {
::?CLASS.new( :$name, :$price )
}
…
@products .= map: Product::from-JSON-list;
你得到这个错误的原因是你正在构造一个 List
of List
s of Pair
s 但把它当作 List
of [=15] =]es.
代码最简单的修复是更新数据结构以匹配您的处理方式:
my @products = (
{name => "samsung s6" , price => "600"},
{name => "samsung s7" , price => "700"}
);
本例中的 {}
被评估为 Hash
构造函数。我认为问题出在 Raku =>
是一个 Pair
构造函数而不是一个特殊的逗号。
正如其他人所建议的那样,轻量级对象也很有用,但我认为了解如何构建您认为您正在构建的东西是很好的。
已经有很好的答案了。 Brad 的 Hash()
强制解决方案太棒了!
但感觉需要另一个答案。没有人直接讨论你使用 .kv
走 key/value 路线的冲动,以及你得到的错误:
由于数据的性质,I would also like to iterate using the
.kv
method ... "Malformed parameter"
.kv
没有帮助
您的数据 .kv
不会帮助您到达需要去的地方。 (这就是为什么没有人使用它的原因。)
为什么不呢?
这是您的数据:
(name => "samsung s6" , price => "600"),
(name => "samsung s7" , price => "700"),
...
@products
中的每个元素都是两个 key/value 对的 sub-list。
但是 所有 键 无用!
你真正想做的是扔掉现有的键,然后构建全新的对 通过将每个 @products
元素中第一对的 value 视为 new 键和 第二对的 value 作为关联的 value.
所以你最终会得到这样的结果:
("samsung s6" => "600"),
("samsung s7" => "700"),
为此,您需要忘记 .kv
。
相反,您需要适当地将 .value
例程与 .pairup
例程相结合。确实有效:
.say for @products[*;*]».value.pairup
显示:
samsung s6 => 600
samsung s7 => 700
让我们分解一下:
.say for @products[*;*]
显示:
name => samsung s6
price => 600
name => samsung s7
price => 700
有关 [*;*]
正在做什么的解释,请参阅
如前所述,这些键是无用的。我们想要每个 Pair
:
.say for @products[*;*]».value
显示:
samsung s6
600
samsung s7
700
A »
在这种情况下就像一个内部 for
循环,或 map
。例如,我可以这样写:
.value.say for (do @$_ for @products[*;*])
但是只写一个字»
要容易得多。这摆脱了额外的括号,内部 for
构造,以及什么不是。
最后我们在末尾添加一个 .pairup
来配对列表的奇数和偶数元素;每个 odd 元素成为一个键,后面的(偶数)元素成为关联值。工作完成。
关于错误信息
错误消息包含 ⏏
。这是一个“弹出”符号,指出解析器放弃的位置:
------> for @products -> $x⏏.kv
“格式错误的参数”一词在您的代码中调用了 .
:
for @products -> $x.kv ...
$x
已被解析为参数,或者至少是一个参数的开头。但是 .
是怎么回事?如果它是表达式的一部分,它可能会调用方法调用,但在这里您应该完成指定参数名称的操作。所以解析器保释。