raku Какой лучший способ сделать ротор с конца? - PullRequest
6 голосов
/ 30 апреля 2020

Если данные в конце списка более важны, и я хочу: частичный список оставить в начале списка при сохранении начального порядка, я делаю это:

> my @a = (0,1,2,3,4,5,6,7,8,9);
[0 1 2 3 4 5 6 7 8 9]
> say @a.rotor(4, :partial)
((0 1 2 3) (4 5 6 7) (8 9)) # not what I want; important data at end gets cut off;
> say @a.reverse.rotor(4, :partial).reverse.map({$_.reverse});
((0 1) (2 3 4 5) (6 7 8 9)) # this is what I want

Is Есть ли способ избежать 3 "обратных" операций? Можно ли добавить наречие: fromEnd?

Ответы [ 4 ]

5 голосов
/ 30 апреля 2020

Вы можете использовать @a.rotor(2,4,4) или чуть более универсально @a.rotor(@a % 4,slip 4 xx *). Конечно, вы можете определить функцию

multi batch ( $_, $n, :from-end($)! ) {
    .rotor: .elems % $n, slip $n xx *
}
say batch  ^10,  4,:from-end; #or even
say (^10).&batch(4):from-end;
4 голосов
/ 30 апреля 2020
my @a = (0,1,2,3,4,5,6,7,8,9);
my @b = @a.rotor(4, :partial)».elems.reverse;
say @a.rotor(|@b);
3 голосов
/ 30 апреля 2020

Сначала рассмотрим последний вопрос: да, это возможно, но для согласованности его, вероятно, назовут :end, и нет, я не думаю, что он, вероятно, будет добавлен. Но тогда я могу ошибаться: -)

Я не уверен, как выглядит ваш пример игры в гольф, но если вы действительно работаете с массивом, почему бы не заполнить его сначала значениями, чтобы сделать его равномерно делимым на 4, а затем снова удалите их:

my @a = ^10;
@a.splice(0,0, Any xx @a % 4);
say @a.batch(4);  # (((Any) (Any) 0 1) (2 3 4 5) (6 7 8 9))

Примечание. Я использовал более короткое значение ^10 (которое находится в диапазоне от 0 до 10, исключая конечную точку). И я использовал более простой метод batch, поскольку мы уверены, что частичных списков не будет. В любом случае, reverse не требуется, просто проверка значений впоследствии.

Обратите внимание, метод reverse в массиве относительно дешев, так как фактически не перемещает никакие значения.

1 голос
/ 07 мая 2020

Вы можете рассчитать количество элементов, оставшихся в списке :partial.

@a.elems % 4

Затем объедините его с повторяющейся последовательностью нужного вам размера.

4 xx *

Если Вы пытались объединить их просто, это не сработает

@a.elems % 4, 4 xx *

Это потому, что выше приведен список из двух элементов. Первый - результат операции модуля, а второй - бесконечная последовательность.

Вы можете просто использовать flat, чтобы сделать их единой последовательностью.

flat @a.elems % 4, 4 xx *

Вот результирующий код.

@a.rotor( flat @a.elems % 4, 4 xx * )
...