Como atribuir valores com foreach?

Como atribuir valores com foreach?

Tenho problemas para atribuir valores com \foreach. Alguém pode me ajudar? O código a seguir está errado. O objetivo é definir os valores: \lx1=1, \ly1=2, \lz1=3, por exemplo.

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

Responder1

Existem vários motivos pelos quais isso não funciona:

  • \lx1não é um nome de comando, consiste no comando \lx, seguido de dígito 1. Substitua 1por uma letra ou o uso fica um pouco mais complexo via \csname.

  • \xe \ycontém os valores x e y, a definição de \xdefine \x, não a macro interna e \yque muda a cada loop. \expandafterexpande uma macro em um nível:

    \expandafter\def\x{...}
    

    Fazer o mesmo \yrequer muito mais \expandafter, portanto, usar \let é mais fácil aqui.

  • \foreachcoloca o corpo do loop dentro de grupos, portanto as definições locais serão perdidas. Isso pode ser resolvido por definições globais.

Exemplo:

\usepackage{pgffor}

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

Ou com \lx1como macro:

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

Adição para os fãs de \expandafter:

\gdefpode ser usado em vez de \global\letusar adicional \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}

Como pode ser visto, a versão com \leté mais eficiente e elegante.

informação relacionada