.elems - 1
вызывает метод для $_
, что, вероятно, неправильно.
Если вы собираетесь написать это так $!my-array.elems - 1
, или вы можете задать лямбду *.elems - 1
. Обычная лямбда равна * - 1
(массив нумеруется до количества элементов).
В этом случае я бы просто использовал Whither *
.
$!my-array[$index + 1 .. *]
Чтобы for
вернул результат, добавьте к нему префикс 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
возвращает 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
должен вернуть Order
(Less
, Same
, More
).
Таким образом, правильный оператор для настройки будет &infix:«cmp»
.