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 * )