¿Cómo asignar valores con foreach?

¿Cómo asignar valores con foreach?

Tengo problemas para asignar valores con \foreach. ¿Puede alguien ayudarme? El siguiente código es incorrecto. El propósito es asignar los valores: \lx1=1, \ly1=2, \lz1=3, por ejemplo.

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

Respuesta1

Hay varias razones por las que esto no funciona:

  • \lx1no es un nombre de comando, consta del comando \lxseguido de un dígito 1. O reemplácelo 1por una letra o el uso es un poco más complejo a través de \csname.

  • \xy \ycontiene los valores xey, la definición de \xdefine \x, no la macro interna y \ycambiará con cada ciclo. \expandafterexpande una macro un nivel:

    \expandafter\def\x{...}
    

    Hacer lo mismo con \yrequiere mucho más \expandafter, por lo tanto, usarlo \let es más fácil aquí.

  • \foreachcoloca el cuerpo del bucle dentro de grupos, por lo que se perderán las definiciones locales. Esto se puede resolver mediante definiciones globales.

Ejemplo:

\usepackage{pgffor}

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

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

Adición para los fanáticos de \expandafter:

\gdefse puede utilizar en lugar de \global\letutilizar 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 se puede observar, la versión con \letes más eficiente y elegante.

información relacionada