Wie weise ich mit foreach Werte zu?

Wie weise ich mit foreach Werte zu?

Ich habe Probleme, Werte mit zuzuweisen \foreach. Kann mir jemand helfen? Der folgende Code ist falsch. Der Zweck besteht darin, die Werte zuzuweisen: \lx1=1, \ly1=2, \lz1=3, zum Beispiel.

\foreach \x/\y in {\lx1/1,\ly1/2,\lz1/3}
{%
\def\x{\y}
\x{\y}
{

Antwort1

Dass dies nicht funktioniert, hat mehrere Gründe:

  • \lx1ist kein Befehlsname, sondern besteht aus dem Befehl \lx, gefolgt von einer Ziffer 1. Entweder durch einen Buchstaben ersetzen 1oder die Verwendung ist über etwas komplexer \csname.

  • \xund \yenthalten die x- und y-Werte, die Definition von \xdefines \x, nicht das Makro darin und \yändern sich mit jeder Schleife. \expandaftererweitert ein Makro um eine Ebene:

    \expandafter\def\x{...}
    

    Das Gleiche mit zu tun, \yerfordert viel mehr \expandafter, deshalb \let ist die Verwendung hier einfacher.

  • \foreachplatziert den Schleifenkörper in Gruppen, wodurch lokale Definitionen verloren gehen. Dies kann durch globale Definitionen gelöst werden.

Beispiel:

\usepackage{pgffor}

\foreach \x/\y in {\lxA/1,\lyA/2,\lzA/3}
{%
  \global\expandafter\let\x\y
}

Oder mit \lx1als Makro:

\foreach \x/\y in {\lx1/1,\ly1/2,\lz1/3}
{%
  \begingroup
    \escapechar=-1 % suppresses backslash with \string
    \global\expandafter\let
    \csname \expandafter\string\x\endcsname\y
  \endgroup
}

\typeout{\expandafter\string\csname lx1\endcsname:
  \expandafter\meaning\csname lx1\endcsname}

Ergänzung für die Fans von \expandafter:

\gdefkann anstelle von verwendet werden, \global\letindem zusätzlich verwendet wird \expandafter:

\foreach \x/\y in {\lxA/1,\lyA/2,\lzA/3}
{%
  \expandafter\expandafter\expandafter
  \gdef\expandafter\x\expandafter{\y}%
}

\typeout{\string\lxA: \meaning\lxA}

\foreach \x/\y in {\lx1/1,\ly1/2,\lz1/3}
{%
  \begingroup
    \escapechar=-1 % suppresses backslash with \string
    \expandafter\gdef
    \csname \expandafter\string\x\expandafter\endcsname
    \expandafter{\y}%
  \endgroup
}

\typeout{\expandafter\string\csname lx1\endcsname:
  \expandafter\meaning\csname lx1\endcsname}

Wie man sieht, \letist die Version mit effizienter und eleganter.

verwandte Informationen