6
$\begingroup$

Is there any way to make cyclic loop over array without PadLeft,PadRight, ArrayPad?
So supposed operator DoC works like this:

arr = {1,2,3};
DoC[Print@e, {e, arr}, 10]

Output: 1, 2, 3, 1, 2, 3, 1, 2, 3, 1
(*At least 10 cyclically repeated elements of arr*)

UPD
Well, in a way it’s a learning question, for comparison of Mathematica' possibilities.
Thanks for the answers, I learned many useful features.
As to the substance looks like for big arrays the best method is with QuotientRemainder, and for small enough built-in padding is good.

$\endgroup$
4
  • 2
    $\begingroup$ n = 10; Table[{a, b, c}[[Mod[n, 3, 1]]], {n, 1, n}] $\endgroup$ Commented Dec 26, 2024 at 16:11
  • $\begingroup$ @cvgmy Only problem is that integer mod is typically one of the slowest machine instructions available. =/ $\endgroup$ Commented Dec 26, 2024 at 16:38
  • $\begingroup$ Sounds like an XY problem. Why not use padding? $\endgroup$ Commented Dec 27, 2024 at 0:09
  • $\begingroup$ What kind of operations $f$ you want to apply on the cyclic list? Suppose $f$ is very time-consuming but of parallelizable type (no side effects). Then apply $f$ first on arr only, and then make a cycle from the resulting answer list. The existing solution repeats the same computation many times. $\endgroup$ Commented Dec 27, 2024 at 7:54

7 Answers 7

4
$\begingroup$

You could use "Mod" to get the correct index and "Sow"/"Reap" to assemble the new list:

doc[list_, n_] := Module[{len = Length[list]},
  Reap[
    Do[Sow[list[[Mod[i, len, 1]]]], {i, n}]
    ][[2, 1]]
  ]

With this:

doc[{1, 2, 3}, 10]

{1, 2, 3, 1, 2, 3, 1, 2, 3, 1}
$\endgroup$
4
$\begingroup$

This one uses a single QuotientRemainder and a loop unrolling instead of a Mod in each single iteration. It also does not create any copies of arr:

ClearAll[DoC];
DoC[f_, arr_, k_] := Module[{q, r},
   {q, r} = QuotientRemainder[k, Length[arr]];
   Do[Scan[f, arr], q];
   Do[f[arr[[i]]], {i, 1, r}];
   ];
$\endgroup$
4
$\begingroup$

Using Table and Take:

DoC[list_, n_] := Take[Flatten@Table[list, {Ceiling[n/Length[list]]}], n]

list = {1, 2, 3};

DoC[list, 10]

{1, 2, 3, 1, 2, 3, 1, 2, 3, 1}

$\endgroup$
3
$\begingroup$

One way could be:

arr = {1, 2, 3};
min = 10;
DoC[k_List, min_] := 
 NestWhile[Join[#1, #1] &, k, Length@# < min &] // Take[#, min] &

Table[DoC[arr, i], {i, 5, 15, 2}] // Grid

repeating list elements

$\endgroup$
1
  • $\begingroup$ Well, but it looks like just version of ArrayPad $\endgroup$ Commented Dec 26, 2024 at 16:01
2
$\begingroup$

A version using RotateLeft:

DoC[arr_, n_] := NestList[RotateLeft, arr, n - 1][[;; , 1]]
$\endgroup$
1
  • $\begingroup$ Yes, it's interesting compromise between padding and Mod ! $\endgroup$ Commented Dec 29, 2024 at 15:38
2
$\begingroup$
arr = Alphabet[][[;; 3]]

Update

Partition[arr, 10, 4, 1]

(* {{a, b, c, a, b, c, a, b, c, a}}
Partition[arr, #, 4, 1] & /@ Range[11]

(* {
    {{a}},
    {{a,b}},
    {{a,b,c}},
    {{a,b,c,a}},
    {{a,b,c,a,b}},
    {{a,b,c,a,b,c}},
    {{a,b,c,a,b,c,a}},
    {{a,b,c,a,b,c,a,b}},
    {{a,b,c,a,b,c,a,b,c}},
    {{a,b,c,a,b,c,a,b,c,a}},
    {{a,b,c,a,b,c,a,b,c,a,b}}
   } *)

A 'point-free' version:

(CurryApplied[4 -> {1, 4, 3, 2}][Partition][arr, 1, 4] /@ Range[11])

(* {{{a}},{{a,b}},{{a,b,c}},{{a,b,c,a}},{{a,b,c,a,b}},   
   {{a,b,c,a,b,c}},{{a,b,c,a,b,c,a}},{{a,b,c,a,b,c,a,b}},
   {{a,b,c,a,b,c,a,b,c}},{{a,b,c,a,b,c,a,b,c,a}},
   {{a,b,c,a,b,c,a,b,c,a,b}}} *)

Original Answer

SubstitutionSystem[MapApply[Rule]@Partition[arr, 2, 1, 1], First@arr, 9] 
  // Flatten

(* {a, b, c, a, b, c, a, b, c, a} *)
$\endgroup$
2
$\begingroup$

Version 14.3 introduced Cyclic to represent a cyclic sequence of elements.

DoC[list_, n_] := Table[Cyclic[list][i], {i, n}]

DoC[{1, 2, 3}, 10]
(* {1, 2, 3, 1, 2, 3, 1, 2, 3, 1} *)
$\endgroup$

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.