将命令作为参数从“forarray”传递给“\DefineArrayVar”

将命令作为参数从“forarray”传递给“\DefineArrayVar”

我需要1,2,3,...,\Num从​variable list\DefineArrayVarforarray包裹。如果我手动传递它,一切都会正常工作,但是,当我传递命令时,\DefineArrayVar就会变得混乱并失败。

这是我的 MWE:

\documentclass{article}

\usepackage{forloop}
\usepackage{forarray}

\newcommand{\Num}{4}

\newcounter{ct}
\setcounter{ct}{1}

\newcommand{\test}{%
    \forloop{ct}{1}{\value{ct}<\Num}{\thect,}\thect%
}

\DefineArrayVar{ArrayName}{@}
{,}{1,2,3,4} % <---- This works 
% {,}{\test} % <---- This doesn't work
% {,}{\forloop{ct}{1}{\value{ct} < \Num}{\thect,}\thect} % <---- This doesn't work either
{,}{4cm,0.8cm,0.6cm,1.6cm}

% This doesn't work
% \expandafter\DefineArrayVar\expandafter{ArrayName}{@}{,}{\test}{,}{4cm,0.8cm,0.6cm,1.6cm}

\DefineArrayDefault{,}{@}{2}{2}{ArrayName}

\begin{document}

\test % To see what 'forloop' is generating

\ArrayName % Proof that it's working (must print "0.8cm")

\end{document}

基于这个答案这个答案(这与我的问题非常相关),我也尝试过(单独)使用\expandafter\edef像这样:

    \expandafter\DefineArrayVar\expandafter{ArrayName}{@}{,}{\test}{,}{4cm,0.8cm,0.6cm,1.6cm}
    \edef\test{\unexpanded\expandafter{\forloop{ct}{1}{\value{ct}<\Num}{\thect,}\thect}}

但它不起作用。

好吧,由于我不清楚自己在做什么,所以我无法继续。我该如何让它工作?

答案1

您会考虑使用不同的包来存储和调用数组吗?

listofitems支持数组构造,并且其数组存储技术是完全可扩展的(也就是说,一旦读取,数组元素的调用是完全可扩展的)。

它还支持多维数组。

\documentclass{article}
\usepackage{listofitems}
\begin{document}
\readlist*\ArrayName{4cm,0.8cm,0.6cm,1.6cm}

ArrayName[2] is \ArrayName[2]

The array has \listlen\ArrayName[] elements.

The whole array is \foreachitem\z\in\ArrayName[]{\ifnum\zcnt=1\else,\fi\z}
\end{document}

在此处输入图片描述

答案2

forloop和软件包forarray确实过时了。有了它,expl3您可以获得更多功能,同时提高灵活性。

您的需求只需“一行”即可满足。

\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\definelist}{mm}
 {% #1 = list name, #2 = items
  \clist_clear_new:c { l_leone_list_#1_clist }
  \clist_set:cn  { l_leone_list_#1_clist } { #2 }
 }
\NewExpandableDocumentCommand{\getlistitem}{mm}
 {% #1 = list name, #2 = number of item to retrieve
  \clist_item:cn  { l_leone_list_#1_clist } { #2 }
 }
\NewExpandableDocumentCommand{\getlistlen}{m}
 {% #1 = list name
  \clist_count:c  { l_leone_list_#1_clist }
 }

\ExplSyntaxOff

\definelist{ArrayName}{4cm,0.8cm,0.6cm,1.6cm}

\begin{document}

\getlistitem{ArrayName}{4}

X\makebox[\getlistitem{ArrayName}{4}][s]{a\hfil a}X

X\hspace*{1.6cm}X

\end{document}

最后一个例子表明您可以\getlistitem在任何需要长度的情况下使用它,因为列表包含长度。

在此处输入图片描述

相关内容