根据参数对数据工具中的数据进行排序

根据参数对数据工具中的数据进行排序

我对乳胶编程还很陌生(我经常用它来写文本)。我试图在数据工具数据库中插入数据,然后根据其中一个字段对数据进行排序。但是,如果这个字段是通过宏参数填充的,那么只有当参数本身不是另一个宏的结果。代码如下:

\documentclass{article}

 \usepackage{datatool}

\newcommand{\sortitem}[3]{%
   \DTLnewrow{list}%
   \DTLnewdbentry{list}{value}{#1}%
   \DTLnewdbentry{list}{label}{#2}%
   \DTLnewdbentry{list}{description}{#3}%
}

\newcommand{\aaa}{a}
\newcommand{\fff}{f}
\newcommand{\bbb}{b}
\newcommand{\zzz}{z}
\newcommand{\ccc}{c}

\newenvironment{sortedlist}%
{%
   \DTLifdbexists{list}{\DTLcleardb{list}}{\DTLnewdb{list}}%
}%
{%
   \DTLsort*{value}{list}%
   \begin{enumerate}
     \DTLforeach*{list}{\theLabel=label,\theDesc=description, \theValue=value}{%
       \item \theValue~\theLabel
     }%

     \end{enumerate}%
} 
\begin{document}

Sorted:

\begin{sortedlist}
   \sortitem{a}{item}{opt}
   \sortitem{f}{item}{opt}
   \sortitem{b}{item}{opt}
   \sortitem{z}{item}{opt}
   \sortitem{c}{item}{opt}
\end{sortedlist}

Not sorted:

 \begin{sortedlist}
   \sortitem{\aaa}{item}{opt}
   \sortitem{\fff}{item}{opt}
   \sortitem{\bbb}{item}{opt}
   \sortitem{\zzz}{item}{opt}
   \sortitem{\ccc}{item}{opt}
\end{sortedlist}

\end{document}

输出是:

Sorted:

1. a item
2. b item
3. c item
4. f item
5. z item

Not sorted (wrong):

1. a item
2. f item
3. b item
4. z item
5. c item

也就是说,在第一种情况下如预期的那样,但在第二种情况下却不是。我怀疑这是由于宏扩展的顺序造成的,因此我尝试插入\expandafter但没有成功。有人能解释一下这个问题,给我一些线索,告诉我该调查什么吗?

编辑: koleygr 解决方案确实有效。但是,如果我引入更复杂的宏,例如:

\usepackage[first=1, last=9]{lcg}
\newcommand{\random}{\rand\arabic{rand}}
...
 \begin{sortedlist}
   \sortitem{\random}{item}{opt}
   \sortitem{\random}{item}{opt}
   \sortitem{\random}{item}{opt}
   \sortitem{\random}{item}{opt}
   \sortitem{\random}{item}{opt}
\end{sortedlist}

Latex 不再编译(TeX 容量超出,抱歉 [输入堆栈大小=5000])。我尝试更改输入堆栈大小,但没有帮助。另一方面,如果我定义\random为健壮命令,情况会回到之前的情况(数据库没有按预期排序)。还有其他线索吗?

答案1

根据编辑的要求进行了更改

\documentclass{article}
\usepackage{datatool}
\usepackage{tikz}
 %\def\random#1{\pgfmathparse{random(#1)}\pgfmathresult} %<-This or any 
 % simmilar I tied doesn't work

\newcommand{\sortitem}[3]{%
   \DTLnewrow{list}%
   \dtlexpandnewvalue
   \DTLnewdbentry{list}{value}{#1}%
   \DTLnewdbentry{list}{label}{#2}%
   \DTLnewdbentry{list}{description}{#3}%
}

\newcommand{\aaa}{a}
\newcommand{\fff}{f}
\newcommand{\bbb}{b}
\newcommand{\zzz}{z}
\newcommand{\ccc}{c}

\newenvironment{sortedlist}%
{%
   \DTLifdbexists{list}{\DTLcleardb{list}}{\DTLnewdb{list}}%
}%
{%
   \DTLsort*{value}{list}%
   \begin{enumerate}

     \DTLforeach*{list}{\theLabel=label,\theDesc=description, \theValue=value}{%
       \item \theValue~\theLabel
     }%

     \end{enumerate}%
} 
\begin{document}

Sorted:

\begin{sortedlist}
   \sortitem{a}{item}{opt}
   \sortitem{f}{item}{opt}
   \sortitem{b}{item}{opt}
   \sortitem{z}{item}{opt}
   \sortitem{c}{item}{opt}
\end{sortedlist}

Not sorted:

\foreach \i in {1,...,5}{
\pgfmathparse{random(9)}
\expandafter\xdef\csname MyItem\i\endcsname{\pgfmathresult}

Item\i=\pgfmathresult\par
}

Sorted:
\begin{sortedlist}
\foreach \i in {1,...,5}{
  \sortitem{\csname MyItem\i\endcsname}{item}{opt} 
}
\end{sortedlist}\vspace*{10pt}

\begin{sortedlist}
\foreach \i in {\aaa,\bbb,\ccc,\zzz,\fff}{
  \sortitem{\i}{item}{opt} 
}
\end{sortedlist}

\end{document}

上述代码给出以下结果:

在此处输入图片描述

您可以找到在 tikz 包的帮助下使用随机数的方法。使用注释\random命令或任何类似命令都没有给我想要的结果。数字每次都在变化,在排序过程中也是如此。但我认为您可以像上面一样完成您的工作。

旧答案

您必须使用以下方式扩展值\dtlexpandvalue

\documentclass{article}

 \usepackage{datatool}

\newcommand{\sortitem}[3]{%
   \DTLnewrow{list}%
   \dtlexpandnewvalue
   \DTLnewdbentry{list}{value}{#1}%
   \DTLnewdbentry{list}{label}{#2}%
   \DTLnewdbentry{list}{description}{#3}%
}

\newcommand{\aaa}{a}
\newcommand{\fff}{f}
\newcommand{\bbb}{b}
\newcommand{\zzz}{z}
\newcommand{\ccc}{c}

\newenvironment{sortedlist}%
{%
   \DTLifdbexists{list}{\DTLcleardb{list}}{\DTLnewdb{list}}%
}%
{%
   \DTLsort*{value}{list}%
   \begin{enumerate}
     \DTLforeach*{list}{\theLabel=label,\theDesc=description, \theValue=value}{%
       \item \theValue~\theLabel
     }%

     \end{enumerate}%
} 
\begin{document}

Sorted:

\begin{sortedlist}
   \sortitem{a}{item}{opt}
   \sortitem{f}{item}{opt}
   \sortitem{b}{item}{opt}
   \sortitem{z}{item}{opt}
   \sortitem{c}{item}{opt}
\end{sortedlist}

Not sorted:

 \begin{sortedlist}
   \sortitem{\aaa}{item}{opt}
   \sortitem{\fff}{item}{opt}
   \sortitem{\bbb}{item}{opt}
   \sortitem{\zzz}{item}{opt}
   \sortitem{\ccc}{item}{opt}
\end{sortedlist}

\end{document}

在这里找到:Datatool \DTLnewdbentry 不接受关键列的值但这个答案适用于多个扩展(你或其他有类似问题的人可能需要)

相关内容