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
    Mar 2 '15 at 19:50
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
    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$
4
  • $\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.