11
$\begingroup$

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.

$\endgroup$

4 Answers 4

9
$\begingroup$
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_}

$\endgroup$
2
  • 1
    $\begingroup$ The middle one will fail if x1=1. $\endgroup$
    – Kuba
    Aug 28, 2018 at 7:37
  • $\begingroup$ @Kuba, good point. $\endgroup$
    – kglr
    Aug 28, 2018 at 8:09
8
$\begingroup$

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_}

$\endgroup$
4
  • 2
    $\begingroup$ It won't work if x1 = 1. $\endgroup$
    – Kuba
    Aug 28, 2018 at 7:36
  • $\begingroup$ Function[{sym},Pattern[sym,Blank[]],{HoldFirst}] instead of Pattern[#,Blank[]]& as usual. $\endgroup$ Aug 28, 2018 at 7:44
  • $\begingroup$ @Kuba what exactly do you mean by x1 = 1 ? $\endgroup$
    – Winkelried
    Aug 28, 2018 at 8:57
  • $\begingroup$ @Winkelried if any of xi have values prior to that evaluation then you will get e.g. Pattern[1, Blank[]] $\endgroup$
    – Kuba
    Aug 28, 2018 at 8:58
6
$\begingroup$

Nothing new but shorter:

StringTemplate["x``_"] /@ Range[10] // ToExpression
{x1_, x2_, x3_, x4_, x5_, x6_, x7_, x8_, x9_, x10_}
$\endgroup$
2
  • $\begingroup$ 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. $\endgroup$ May 3, 2022 at 7:38
  • 1
    $\begingroup$ @JulesManson thanks for kind words, one liners are nice for a hands-on prototyping but in general I'd trade compactness for readability. :) $\endgroup$
    – Kuba
    May 4, 2022 at 6:52
3
$\begingroup$

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.

$\endgroup$
4
  • $\begingroup$ It won't work if x1 = 1 $\endgroup$
    – Kuba
    Aug 28, 2018 at 7:36
  • $\begingroup$ @Kuba You mean if the symbols have values? $\endgroup$
    – C. E.
    Aug 28, 2018 at 9:48
  • $\begingroup$ Yes, sorry for not being clear. $\endgroup$
    – Kuba
    Aug 28, 2018 at 9:54
  • $\begingroup$ @Kuba Well, you are right. I wanted to show how to adapt the answer OP linked to, but it has this flaw. $\endgroup$
    – C. E.
    Aug 28, 2018 at 10:40

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.