在 Perl6 中制作部分数组
Making a partial array in Perl6
有什么好的方法可以从另一个数组中获取部分数组吗?
示例:给定一个包含 x 个元素的数组,以及一个在该数组元素范围内的 Int $index
,我想 运行 从 $index + 1
到元素数量 - 1.
基本上我想比较数组中的所有元素。比较是元素本身的函数。 (注意我知道函数eqv
,虽然这不适合这种特殊情况)
我在想类似的事情:
for $!my-array.kv -> $index, $element
{
for $!my-array[$index+1 .. .elems-1] -> $another-element
{
$element.compare($another-element)
}
}
您可以使用 combinations
来避免双重 for
循环。假设你不想记录索引,它可以像这样简单:
for @($!my-array).combinations: 2 -> ( $element, $another-element ) {
$element.compare($another-element);
}
.elems - 1
在 $_
上调用了一个方法,这可能是错误的。
如果你打算那样写 $!my-array.elems - 1
,或者你可以给它一个 lambda *.elems - 1
。通常的 lambda 是 * - 1
(一个数组 numifies 到元素的数量)。
在这种情况下,我只会使用 Whatever *
.
$!my-array[$index + 1 .. *]
要获得 for
到 return 的结果,请在其前面加上 do
。
my @result = do for $!my-array.kv -> $index, $element
{
do for $!my-array[$index + 1 .. *] -> $another-element
{
$element.compare($another-element)
}
}
使用map
可能更清楚
$!my-array.kv.map: -> $index, $element {
$!my-array[$index + 1 .. *].map: -> $another-element {
$element.compare($another-element)
}
}
既然你提到 eqv
不合适,这让我相信 .compare
returns True
当它们是等价的,而 False
否则。
那么eqv
其实是合适的。你只需要先调整它。
class Foo {
method compare (Foo:D: Foo:D $other ) {…}
…
}
# this gets mixed into the existing &infix:«eqv»
# mark it for export so that it is available in other code units
multi sub infix:«eqv» ( Foo:D \left, Foo:D \right ) is export {
left.compare(right)
}
# must import it everywhere you want the special cased &infix:«eqv»
# as operators are lexically scoped
use Foo;
$!my-array.kv.map: -> $index, $element {
# cross using &infix:«eqv»
$element X[eqv] $!my-array[$index + 1 .. *]
}
您也可以使用 «eqv«
(<<eqv<<
)。
您写的内容恰好与combinations
非常吻合。
my @result = $!my-array.combinations(2).map(
-> ( $a, $b ) { $a eqv $b }
)
这会生成一个平面列表。
< a b c d e >.combinations(2).map: -> ($element, $another-element){
$element cmp $another-element
}
# (Less,Less,Less,Less,Less,Less,Less,Less,Less,Less)
虽然前面的代码生成了一个列表列表。 (多了一个空的)
my @a = < a b c d e >;
say @a.kv.map: -> $index, $value {
@a[$index ^.. *].map: $value cmp *
}
# (
# (Less,Less,Less,Less),
# (Less,Less,Less),
# (Less,Less),
# (Less,),
# (),
# )
请注意,您可以用多种方式拼写中缀运算符的名称 eqv
&infix:« eqv »
&infix:< eqv >
&infix:[ 'eqv' ]
&[eqv]
在声明新的 multi sub
实现时,除最后一个之外的所有都可以使用。
(删除 &
后)
P.S。我认为一个名为 .compare
的方法应该 return 一个 Order
(Less
,Same
,More
).
那么正确的调整运算符将是 &infix:«cmp»
.
有什么好的方法可以从另一个数组中获取部分数组吗?
示例:给定一个包含 x 个元素的数组,以及一个在该数组元素范围内的 Int $index
,我想 运行 从 $index + 1
到元素数量 - 1.
基本上我想比较数组中的所有元素。比较是元素本身的函数。 (注意我知道函数eqv
,虽然这不适合这种特殊情况)
我在想类似的事情:
for $!my-array.kv -> $index, $element
{
for $!my-array[$index+1 .. .elems-1] -> $another-element
{
$element.compare($another-element)
}
}
您可以使用 combinations
来避免双重 for
循环。假设你不想记录索引,它可以像这样简单:
for @($!my-array).combinations: 2 -> ( $element, $another-element ) {
$element.compare($another-element);
}
.elems - 1
在 $_
上调用了一个方法,这可能是错误的。
如果你打算那样写 $!my-array.elems - 1
,或者你可以给它一个 lambda *.elems - 1
。通常的 lambda 是 * - 1
(一个数组 numifies 到元素的数量)。
在这种情况下,我只会使用 Whatever *
.
$!my-array[$index + 1 .. *]
要获得 for
到 return 的结果,请在其前面加上 do
。
my @result = do for $!my-array.kv -> $index, $element
{
do for $!my-array[$index + 1 .. *] -> $another-element
{
$element.compare($another-element)
}
}
使用map
$!my-array.kv.map: -> $index, $element {
$!my-array[$index + 1 .. *].map: -> $another-element {
$element.compare($another-element)
}
}
既然你提到 eqv
不合适,这让我相信 .compare
returns True
当它们是等价的,而 False
否则。
那么eqv
其实是合适的。你只需要先调整它。
class Foo {
method compare (Foo:D: Foo:D $other ) {…}
…
}
# this gets mixed into the existing &infix:«eqv»
# mark it for export so that it is available in other code units
multi sub infix:«eqv» ( Foo:D \left, Foo:D \right ) is export {
left.compare(right)
}
# must import it everywhere you want the special cased &infix:«eqv»
# as operators are lexically scoped
use Foo;
$!my-array.kv.map: -> $index, $element {
# cross using &infix:«eqv»
$element X[eqv] $!my-array[$index + 1 .. *]
}
您也可以使用 «eqv«
(<<eqv<<
)。
您写的内容恰好与combinations
非常吻合。
my @result = $!my-array.combinations(2).map(
-> ( $a, $b ) { $a eqv $b }
)
这会生成一个平面列表。
< a b c d e >.combinations(2).map: -> ($element, $another-element){
$element cmp $another-element
}
# (Less,Less,Less,Less,Less,Less,Less,Less,Less,Less)
虽然前面的代码生成了一个列表列表。 (多了一个空的)
my @a = < a b c d e >;
say @a.kv.map: -> $index, $value {
@a[$index ^.. *].map: $value cmp *
}
# (
# (Less,Less,Less,Less),
# (Less,Less,Less),
# (Less,Less),
# (Less,),
# (),
# )
请注意,您可以用多种方式拼写中缀运算符的名称 eqv
&infix:« eqv »
&infix:< eqv >
&infix:[ 'eqv' ]
&[eqv]
在声明新的 multi sub
实现时,除最后一个之外的所有都可以使用。
(删除 &
后)
P.S。我认为一个名为 .compare
的方法应该 return 一个 Order
(Less
,Same
,More
).
那么正确的调整运算符将是 &infix:«cmp»
.