10
$\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$
1
  • $\begingroup$ Closely related: (1633) $\endgroup$
    – Mr.Wizard
    Commented Mar 2, 2015 at 19:50

2 Answers 2

13
$\begingroup$

Yes there is something quite strightforward:

 genCyclic[n_, list_] := PadRight[{}, n, list]
$\endgroup$
5
  • $\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
    Commented Mar 2, 2015 at 16:14
  • $\begingroup$ @rcollyer in case of PadRight[#,n,#]& you can gain one character over {} :) $\endgroup$
    – Kuba
    Commented Mar 2, 2015 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
    Commented Mar 2, 2015 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
    Commented Jul 29, 2015 at 21:27
  • $\begingroup$ @Mr.Wizard as long as my method is correct somehow. :) $\endgroup$
    – rcollyer
    Commented Jul 29, 2015 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$
4
  • $\begingroup$ Weird, I've never seen ArrayPad before, and it's not a new function. +1 $\endgroup$
    – rcollyer
    Commented Mar 2, 2015 at 16:15
  • $\begingroup$ @rcollyer You are not participating here as often as you should then! $\endgroup$
    – Kuba
    Commented Mar 2, 2015 at 16:18
  • $\begingroup$ @Kuba obviously. $\endgroup$
    – rcollyer
    Commented Mar 2, 2015 at 16:19
  • $\begingroup$ Thank you @rcollyer for the vote. It has a few nice built-in paddings. $\endgroup$
    – kglr
    Commented Mar 2, 2015 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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