获取 arrayjob 数组的长度

获取 arrayjob 数组的长度

我想获取 arrajob 数组的长度,遗憾的是该包不提供此功能。目前,每当我添加或删除数组中的元素时,我都必须手动调整长度变量,这很烦人。

我正在使用 LuaLaTeX;我写了下面的代码,它似乎应该可以完成工作

\documentclass{article}

\usepackage{arrayjob}
\usepackage{ifthen}
\usepackage{etoolbox}

\newarray\Test%

\readarray{Test}{%
    A & B & C%
}

\newcommand{\Length}[1]{
    \newboolean{done}
    \setboolean{done}{false}

    \directlua{i = 1}
    \whiledo{\NOT\boolean{done}}{

      \def\Iteration{\directlua{tex.print("\\#1(" .. i .. ")")}}

        \ifx\Iteration\empty
            \setboolean{done}{true}
      \fi
      
      %% \ifnum\directlua{tex.print(i)}=11
      %%   \setboolean{done}{true}
      %% \fi

      %% \directlua{tex.print(i .. " \\#1(" .. i .. ")")}


      \directlua{i = i + 1}
    }

    \directlua{tex.print(i)}
}


\begin{document}
    \Length{Test}
\end{document}

但实际上它只是挂起了。取消注释循环末尾的块将产生以下输出:

在此处输入图片描述

显示所有参数似乎都是正确的,但 \ifx 无法识别该字符串为空。我也尝试将其与另一个空数组元素的宏进行比较,并尝试了 \ifthanelse 和 etoolbox 的 \ifstrempty,但无济于事。

还有其他更好的方法来查找数组的长度吗?或者,您知道上述代码的问题是什么吗?

答案1

我建议改用expl3。它不仅为这类内容提供序列,还允许在其\ExplSyntaxOn/\ExplSyntaxOff块内使用空格和换行符,而不会生成实际的空格和段落。如果没有它,您必须隐藏这些内容,以免在输出中添加错误的空格。

即使您想继续使用arrayjob,您可能也想将其称为arrayjobx。这是一个较新的版本,它使用命令名称\arrayx而不是\array因为使用会覆盖 LaTeX 的矩阵\array内置环境。{array}

然后,有一种更简单、更可靠的方法来获取数组的长度:arrayjobx为每个名为 的数组定义ArrayName一个\total@ArrayName包含长度的宏。当然,默认情况下您不能\total@ArrayName直接输入,因为@不能出现在控制序列中,所以您需要在\makeatletter/之间使用它\makeatother或通过 访问它\csname。既然你想要一个基于名称的包装器,\csname那么正确的工具就是:

\documentclass{article}

\usepackage{arrayjobx}
\usepackage{ifthen}
\usepackage{etoolbox}

\newarray\Test

\readarray{Test}{%
    A&B&C&&D%
}

\newcommand \Length [1] {%
  \begincsname total@#1\endcsname
}


\begin{document}
  \Length{Test}
\end{document}

答案2

正如@DavidCarlisle 所说,这似乎是 \ifx 扩展的问题。

\ifx\Iteration\empty
    \setboolean{done}{true}
\fi

我认为\ifx比较字符串并会扩展其参数,直到找到一个文字值,但实际上它会比较代币并精确扩展。

\empty扩展为空标记\Iteration会扩展一次为\directlua{tex.print("\\#1(" .. i .. ")")},这当然是不是一个空的标记。

我的解决方案是运行 arrayjob \checkArrayName,将值放入\cacheddata。然​​后我使用\cacheddata它将其扩展一次为正确的值。

我还需要修复两个小错误,一个是仅在循环未完成时增加,并且从最后的一个两个中减去一个i,因为循环超出了界限(并且 arrayjob 是 1 索引的)。

\documentclass{article}

\usepackage{arrayjob}
\usepackage{ifthen}

\newarray\Test

\readarray{Test}{
    A & B & C
}

\newcommand{\Length}[1]{
    \newboolean{done}
    \setboolean{done}{false}

    \directlua{i = 1}
    \whiledo{\NOT\boolean{done}}{

      \directlua{tex.print("\\check#1(" .. i ..")")}

      %% \directlua{tex.print(i .. " \\cachedata")}

      \ifx\cachedata\empty
            \setboolean{done}{true}
      \else
        \directlua{i = i + 1}
      \fi


    }

    \directlua{tex.print(i - 1)} % Last i is already out of bounds
}


\begin{document}
    \Length{Test}
\end{document}

可能有更优雅的方法来解决代码中的原始问题,即使用一些 tex 原语来控制扩展,但上述代码确实正确地回答了原始问题。

取消注释注释行以查看更多详细信息:

在此处输入图片描述

相关内容