11

I would like to create a list of arbitrary length:

{x1_, x2_, ...}

Where each of the elements of the list has the full form:

Pattern[xi, Blank[]]

This answer shows how to create a list of symbols:

{x1, x2, ...}

but I don't know how to adapt that to obtain the above.

I intend to use this list in the definition of a function as in here.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Winkelried
  • 233
  • 1
  • 4

4 Answers4

9
Array[ToExpression["x" <> ToString @ # <> "_"] &, {5}]

{x1_, x2_, x3_, x4_, x5_}

FullForm @ %

List[Pattern[x1,Blank[]], Pattern[x2, Blank[]], Pattern[x3, Blank[]], Pattern[x4, Blank[]], Pattern[x5, Blank[]]]

Also

Thread[Pattern[Evaluate@Array[Symbol["x" <> ToString@#] &, {5}], Blank[]]]

{x1_, x2_, x3_, x4_, x5_}

and

ToExpression[Table["x" <> i <> "_", {i, ToString /@ Range[5]}]]

{x1_, x2_, x3_, x4_, x5_}

kglr
  • 394,356
  • 18
  • 477
  • 896
8

If you construct a list of strings instead, you can take advantage of the fact that ToExpression is listable, and supports a 3rd argument that post-processes the output. For example:

ToExpression[
    {"x1", "x2", "x3"},
    StandardForm,
    Pattern[#,Blank[]]&
]

{x1_, x2_, x3_}

Or, creating the list and converting:

ToExpression[
    Table["x" <> ToString@i, {i, 5}],
    StandardForm,
    Pattern[#, Blank[]]&
]

{x1_, x2_, x3_, x4_, x5_}

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
6

Nothing new but shorter:

StringTemplate["x``_"] /@ Range[10] // ToExpression
{x1_, x2_, x3_, x4_, x5_, x6_, x7_, x8_, x9_, x10_}
Kuba
  • 136,707
  • 13
  • 279
  • 740
  • you did again. a quick, simple, short, and robust 1-liner holy grail of MMA. im 58. when i grow up i hope to master MMA as well you. – Jules Manson May 03 '22 at 07:38
  • 1
    @JulesManson thanks for kind words, one liners are nice for a hands-on prototyping but in general I'd trade compactness for readability. :) – Kuba May 04 '22 at 06:52
3

Here is an example of how to make the solution in the link work for this case:

patt = Table[
   With[
    {s = Symbol["x" <> ToString[i]]},
    Pattern[s, Blank[]]
    ], {i, 10}];

Range[10] /. patt :> {x5, x8}

{5, 8}

Using With here is a trick to insert the symbol into Pattern. Since Pattern has the attribute HoldFirst, it would not work to write e.g.

Pattern[Symbol["x" <> ToString[i]], Blank[]]

because Symbol["x" <> ToString[i]] would not be evaluated before it was passed to Pattern, i.e. Pattern would not receive a string as is required.

C. E.
  • 70,533
  • 6
  • 140
  • 264