9
$\begingroup$

Given a list (for example, {3, 5}) I would like to make a function genCyclic[n_, list_] which generates a cyclic patterns of list with length n, such that genCyclic[5, {3, 5}] returns {3, 5, 3, 5, 3} or genCyclic[1, {3, 5}] returns {3}.

My current solution is to use ConstantArray to generate the full cycle parts ({3, 5, 3, 5} in the first example) and append the remaining part ({3}) and then Flatten them. I have to say my method seems too ugly.

In my old memory, which is frequently wrong, though, I thought there was a built-in function with this functionality. After spending some time trying to find such a function and failing, I ended up here.

No matter whether there is a built-in function or not, what is the most natural way to implement genCyclic?

$\endgroup$
11
$\begingroup$

Yes there is something quite strightforward:

 genCyclic[n_, list_] := PadRight[{}, n, list]
$\endgroup$
  • $\begingroup$ I've always done PadRight[list, n, list], so I guess I've been writing more code than I needed to. +1 $\endgroup$ – rcollyer Mar 2 '15 at 16:14
  • $\begingroup$ @rcollyer in case of PadRight[#,n,#]& you can gain one character over {} :) $\endgroup$ – Kuba Mar 2 '15 at 16:19
  • $\begingroup$ truthfully, I usually end up using that form, or using single letter variable names, like PadRight[l, n, l], so that I get the benefits without dealing with the pain. $\endgroup$ – rcollyer Mar 2 '15 at 16:22
  • 2
    $\begingroup$ @rcollyer Your form is superior because the first element of PadRight needs to be packed if possible, and {} is not packable. See this for example. $\endgroup$ – Mr.Wizard Jul 29 '15 at 21:27
  • $\begingroup$ @Mr.Wizard as long as my method is correct somehow. :) $\endgroup$ – rcollyer Jul 29 '15 at 22:01
10
$\begingroup$
gcF = PadRight[#2, #, #2] &;
gcF[5, {3, 5}]
(* {3, 5, 3, 5, 3} *)

You can also use "Periodic" for the third argument of PadRight that specifies the padding:

gcF1 = PadRight[#2, #, "Periodic"] &;

As far as I know, this form of PadRight (and PadLeft) is not documented.

Few more alternatives using ArrayPad, Part or ArrayReshape:

gcF2 = ArrayPad[#2, {0, # - Length@#2}, "Periodic"] &;
gcF3 = #2[[Mod[Range@#, Length@#2, 1]]] &;
gcF4 = ArrayReshape[#2, {#1}, #2] &;
gcF5 = ArrayReshape[#2, {#1}, "Periodic"] &;
$\endgroup$
  • $\begingroup$ Weird, I've never seen ArrayPad before, and it's not a new function. +1 $\endgroup$ – rcollyer Mar 2 '15 at 16:15
  • $\begingroup$ @rcollyer You are not participating here as often as you should then! $\endgroup$ – Kuba Mar 2 '15 at 16:18
  • $\begingroup$ @Kuba obviously. $\endgroup$ – rcollyer Mar 2 '15 at 16:19
  • $\begingroup$ Thank you @rcollyer for the vote. It has a few nice built-in paddings. $\endgroup$ – kglr Mar 2 '15 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.