raku Как лучше сделать ротор с торца?

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

> 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

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

4 ответа

Решение
my @a = (0,1,2,3,4,5,6,7,8,9);
my @b = @a.rotor(4, :partial)».elems.reverse;
say @a.rotor(|@b);

Ты можешь использовать @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;

Сначала отвечая на последний вопрос: да, это возможно, но, вероятно, это будет называться :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 в массиве, относительно дешев, так как фактически не перемещает никаких значений.

Вы можете рассчитать количество элементов, оставшихся в :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 * )
Другие вопросы по тегам