У меня возникли проблемы с присвоением значений с помощью \foreach
. Может кто-нибудь мне помочь? Следующий код неверен. Цель — присвоение значений: \lx1=1
, \ly1=2
, \lz1=3
, например.
\foreach \x/\y in {\lx1/1,\ly1/2,\lz1/3}
{%
\def\x{\y}
\x{\y}
{
решение1
Есть несколько причин, почему это не работает:
\lx1
не является именем команды, оно состоит из команды\lx
, за которой следует цифра1
. Либо замените1
буквой, либо использование будет немного сложнее с помощью\csname
.\x
и\y
содержат значения x и y, определение\x
defines\x
, а не макрос внутри и\y
будет изменяться с каждым циклом.\expandafter
расширяет макрос на один уровень:\expandafter\def\x{...}
Для выполнения того же самого
\y
требуется гораздо больше\expandafter
, поэтому\let
здесь проще использовать .\foreach
помещает тело цикла внутрь групп, таким образом локальные определения будут потеряны. Это можно решить с помощью глобальных определений.
Пример:
\usepackage{pgffor}
\foreach \x/\y in {\lxA/1,\lyA/2,\lzA/3}
{%
\global\expandafter\let\x\y
}
Или с помощью \lx1
макроса:
\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}
Дополнение для фанатов \expandafter
:
\gdef
можно использовать вместо \global\let
с помощью дополнительных \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}
Как видно, версия с \let
более эффективна и элегантна.