for 루프를 생성하는 다양한 방법의 차이점은 무엇입니까?

for 루프를 생성하는 다양한 방법의 차이점은 무엇입니까?

나는 쉼표로 구분된 목록 등을 반복하는 데 사용할 수 있는 다양한 방법에 대해 궁금했습니다. 특히 그들의 다양한 강점과 약점이 궁금했습니다. 즉, 나는 다음과 같은 사항에 대해 궁금했습니다(그러나 이 목록에만 국한되지는 않습니다).

  1. 확장 가능 여부,
  2. 빈 물건을 처리하는 방법,
  3. 불필요한 선행 및 후행 공백을 처리하는 방법
  4. 나중에 사용하기 위해 루프 내에서 정보를 저장하기 위해 \def/를 사용할 수 있는지 또는 /를 \edef사용해야 하는지 여부.\gdef\xdef

특별한 순서는 없지만, 제가 잘 알고 있는 루핑 방법 목록은 다음과 같습니다. 다음 목록에는 \current@item반복에서 현재 항목의 형식을 지정하기 위해 하나의 인수를 사용하는 매크로가 나와 있습니다.

다음의 명령 사용 2ekernal:

%% \@for
\def\@for@myloop#1{%%
  \@for \x:=#1 \do{\current@item \x}}

%% \@tfor (not a comma separated list--probably shouldn't be here)
\def\@tfor@myloop#1{%%
  \@tfor \x:=#1 \do{\if,\x\relax\else\current@item \x\fi}}

etoolbox패키지 사용

%% `etoolbox`:  need to be careful whether passed a macro:
%%  in that case expansion may be necessary to that the 
%%  delimiters are visible to `\forcsvlist`
\def\etoolbox@myloop#1{%%
  \expandafter\forcsvlist
  \expandafter\current@item
  \expandafter{#1}}

pgffor패키지 사용

%% pgffor
\def\pgffor@myloop#1{%%
  \foreach \x in {#1} {\current@item \x}}

홈브루 방법:

%% version a la `ae`
\def\@ae@myloop#1,#2\@nil{%%
  \current@item{#1}%%
  \expandafter\ifx\expandafter\relax\detokenize{#2}\relax\else
    \@ae@myloop#2\@nil
   \fi
}
\def\ae@myloop#1{%%
  \@ae@myloop#1,\@nil
}

그런 다음 다음과 같은 다양한 방법도 있습니다 expl3(상당히 많기 때문에 이것이 전부는 아닙니다).

\tl_map_inline:nn
\tl_map_function:Nn
\clist_map_inline:Nn
\seq_map_inline:Nn

다음은 이들 각각의 결과를 보여주는 MWE입니다(LaTeX3 버전 하나 포함).

\documentclass{article}
\usepackage[margin=0.5in,paperheight=15in]{geometry}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{pgffor}
\usepackage{enumitem}
\makeatletter

\def\my@item@count{0}
\def\step@my@counter{\xdef\my@item@count{\number\numexpr\my@item@count+1\relax}}
%% \rules to emphasize how spaces are seen and treated!
\def\current@item#1{\step@my@counter\item \rule{0.4pt}{2ex}#1\rule{0.4pt}{2ex}}

%% `etoolbox`
\def\etoolbox@myloop#1{%%
  \forcsvlist \current@item {#1}}
  %% but if passed a macro, then it  first needs to be expanded so the delimiters are visible to `\forcsvlist`.  You'll need to write
  %% \expandafter\forcsvlist \expandafter\current@item \expandafter{#1}}

%% \@for
\def\@for@myloop#1{%%
  \@for \x:=#1 \do{\current@item \x}}

%% \@tfor
\def\@tfor@myloop#1{%%
  \@tfor \x:=#1 \do{\current@item \x}}

%% pgffor
\def\pgffor@myloop#1{%%
  \foreach \x in {#1} {\current@item \x}}

%% version a la `ae`
\def\@ae@myloop#1,#2\@nil{%%
  \current@item{#1}%%
  \expandafter\ifx\expandafter\relax\detokenize{#2}\relax\else
    \@ae@myloop#2\@nil
   \fi
}
\def\ae@myloop#1{%%
  \@ae@myloop#1,\@nil
}

\def\listoffruit#1#2#3{%%
  \def\my@item@count{0}%%
  \noindent
  List of type \texttt{#1}: \parbox[t]{3in}{\raggedright#3}
  \begin{itemize}[topsep=4pt,itemsep=2pt]
    \csname#1@myloop\endcsname{#2}%%
  \end{itemize}
  Total number of bulleted items: \my@item@count
  \par \vspace{2ex}\hrule\par \vspace{2ex}
  }

\ExplSyntaxOn
\NewDocumentCommand{\expl@myloop}{ m }
{
  \clist_map_inline:nn{#1}{\current@item {##1}}
}
\ExplSyntaxOff

\makeatother
\def\apples{apples}
\def\bananas{bananas}
\def\cherries{cherries}

\begin{document}

\listoffruit{etoolbox}{apples,, oranges, bananas ,cherries}{Ignores leading spaces and empty items. Trailing spaces not ignored.}

\listoffruit{@for}{apples,, oranges, bananas ,cherries}{Empty lines and trailing or leading spaces not ignored.  Something goes on with last item in list.}

\listoffruit{@tfor}{\apples,{} {oranges}\bananas\cherries}{Spaces ignored, all other token respected, bracketed tokens treated as one.}

\listoffruit{pgffor}{apples,, oranges, bananas ,cherries}{Ignores leading spaces, empty items and trailing spaces not ignored.}

\listoffruit{ae}{apples,, oranges, bananas ,cherries}{Leading or trailing spaces not ignored.  Empty items not ignored.}

\listoffruit{expl}{apples,, oranges, bananas ,cherries}{Trailing or leading spaces ignored.   Empty items ignored.}

\end{document}

여기에 이미지 설명을 입력하세요

내가 알고 있는 문제:

  • 확장이 불가능하다고 생각합니다 \@for.
  • \cslist_map_inline:nn확장 가능하지만 제한이 있습니다. 즉, -type 인수에서는 확장할 수 없습니다 f.
  • pgffor\foreach그룹 내에서 의 루프가 실행되었습니다. 따라서 나중에 사용할 수 있도록 그룹 내의 정보를 사용하거나 저장 \gdef해야 합니다 . \xdeg나는 여기에 제시된 다른 루프 중 어떤 것이 비슷한지 완전히 조사하지 않았습니다.결점(단어 선택이 올바른지 확실하지 않습니다). 확장이 가능한지 아닌지는 잘 모르겠습니다 \foreach.
  • 일부 메서드는 매크로를 통해 명시적으로 전달되든 암시적으로 전달되든 목록을 꽤 훌륭하게 처리합니다. 예를 들어, pgffor's는 \foreach매크로를 통해 전달된 목록으로 무엇을 해야 하는지 알고 있습니다. 을(를) 먼저 확장하려면 해당 매크로 etoolbox\forcsvlist필요합니다. 따라서 a에 대한 첫 번째 그림이 \forcslist그만큼 복잡합니다.

그래서 제가 여기서 관심을 갖는 것은 다음과 같습니다.

  1. 이 게시물의 시작 부분에 항목별로 여기에 제시된 다양한 접근 방식의 강점과 약점을 다루는 응답이지만 다른 중요한 문제를 인식하지 못할 수 있으므로 반드시 이러한 제안으로 제한되지는 않습니다. 예를 들어, 어느 것이 실제로 확실하지 않습니다. 확장 가능합니다.
  2. 알려진 약점 및 강점과 함께 항목 목록을 반복하는 다른 방법을 소개하는 응답입니다.
  3. 확장 가능한 컨텍스트에서 이러한 루프를 사용하려는 현실적인 예를 설명할 수 있는 응답
  4. 나중에 사용하기 위해 그룹 내에서 수집된 정보를 저장하는 방법을 보여주는 응답입니다.

답변1

나는 다른 정의를 제안한다.\current@item

\def\current@item#1{%
  \stepcounter{item@count}
  \item $|$#1$|$\ $|$\texttt{\detokenize{#1}}$|$%
}

따라서 출력에는 실제로 인수로 전달된 내용도 표시됩니다. 그리고 복잡한 관리를 \my@item@count간단한 카운터로 바꾸었습니다. \@tfor쉼표로 구분된 목록용으로 설계되지 않은 다른 도구인 에 대해서는 언급하지 않습니다 .

  1. etoolbox: \forcsvlist후행 공백을 제거하지 않습니다. 당신의 정의는 너무 복잡합니다. 왜냐하면

    %% `etoolbox`
    \def\etoolbox@myloop#1{%%
      \forcsvlist\current@item{#1}}
    

    충분합니다. 항목은 명시적으로 전달됩니다.

  2. \@forLaTeX 커널에 정의된 기본 도구입니다. 선행 및 후행 공백은 제거되지 않습니다. 항목은 \x다음으로 사용되는 제어 시퀀스 로 전달됩니다 \@for.

  3. \foreach후행 공백은 제거되지 않습니다. 항목은 \x다음으로 사용되는 제어 시퀀스 로 전달됩니다 \foreach.

  4. ae\@for확장을 통해 작동하지만 기본적으로 와 같습니다 . 선행 및 후행 공백은 제거되지 않습니다. 항목은 명시적으로 전달됩니다.

  5. expl선행 및 후행 공백뿐만 아니라 빈 항목도 제거합니다. 항목은 명시적으로 전달됩니다.

\documentclass{article}
\usepackage[margin=0.5in,paperheight=15in]{geometry}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{pgffor}
\usepackage{enumitem}
\makeatletter

\newcounter{item@count}
%% \rules to emphasize how spaces are seen and treated!
\def\current@item#1{%
  \stepcounter{item@count}
  \item $|$#1$|$\ $|$\texttt{\detokenize{#1}}$|$%
}

%% `etoolbox`
\def\etoolbox@myloop#1{%%
  \forcsvlist\current@item{#1}}

%% \@for
\def\@for@myloop#1{%%
  \@for \x:=#1\do{\current@item \x}}

%% pgffor
\def\pgffor@myloop#1{%%
  \foreach \x in {#1} {\typeout{pgf:\x}\current@item \x}}

%% version a la `ae`
\def\@ae@myloop#1,#2\@nil{%%
  \current@item{#1}%%
  \if\relax\detokenize{#2}\relax\else
    \@ae@myloop#2\@nil
   \fi
}
\def\ae@myloop#1{%%
  \@ae@myloop#1,\@nil
}

\def\listoffruit#1#2{%%
  \setcounter{item@count}{0}%%
  \noindent
  List of type \texttt{#1}
  \begin{itemize}[topsep=4pt,itemsep=2pt]
    \csname#1@myloop\endcsname{#2}%%
  \end{itemize}
  Total number of bulleted items: \arabic{item@count}%
  \par \vspace{2ex}\hrule\par \vspace{2ex}
  }

\ExplSyntaxOn
\NewDocumentCommand{\expl@myloop}{ m }
{
  \clist_map_inline:nn{#1}{\current@item {##1}}
}
\ExplSyntaxOff

\makeatother

\begin{document}

\listoffruit{etoolbox}{apples,, oranges, bananas ,cherries}

\listoffruit{@for}{apples,, oranges, bananas ,cherries}

\listoffruit{pgffor}{apples,, oranges, bananas ,cherries}

\listoffruit{ae}{apples,, oranges, bananas ,cherries}

\listoffruit{expl}{apples,, oranges, bananas ,cherries}

\end{document}

여기에 이미지 설명을 입력하세요

expl3빈 항목도 고려하는 또 다른 루프를 추가하겠습니다 .

\ExplSyntaxOn
\NewDocumentCommand{\seq@myloop}{ m }
 {
  \seq_set_split:Nnn \l_tmpa_seq { , } { #1 }
  \seq_map_inline:Nn \l_tmpa_seq { \current@item {##1} }
 }
\ExplSyntaxOff

(물론 사용은 \l_tmpa_seq권장되지 않습니다. 새 변수를 할당하는 것이 좋습니다).

여기에 이미지 설명을 입력하세요

비교에는 의심의 여지가 없습니다. \foreach가 우수한 유일한 곳은 와 같은 "불완전한 목록"을 처리하는 것입니다 1,2,...,20.

답변2

LuaLaTeX:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{filecontents}
\begin{document}
    \newcommand{\drawCircle}[1]{\tikz \draw (0,0) circle (#1);}
    \begin{filecontents*}{testlua.lua}
        for i=1,10 do
            tex.print("\\drawCircle{",0.1*i,"}")
        end
    \end{filecontents*}
    \directlua{dofile('testlua.lua')}
\end{document}

관련 정보