Datatool:如何按特定顺序手动选择一些行

Datatool:如何按特定顺序手动选择一些行

我有一个大型的多用途数据库,我想从中选择几个项目(使用标签)并按给定的顺序打印它们,而不是数据库顺序或任何与条目相关的顺序。

例如,我目前使用这个代码(在这个网站上找到,感谢 Peter Grill):

\documentclass{article}  
\usepackage{datatool}
\usepackage{longdata}

\usepackage{filecontents}
\begin{filecontents*}{foo.dat}
Hammer001,   Hammer,    1 ,  0 , 1 , 10 , 1 , light\\
Hammer002,   Hammer,    2 ,  0 , 1 , 10 , 1 , heavy\\
Hammer003,   Hammer,    3 ,  0 , 1 , 10 , 1 , really heavy\\
Longsword001,Longsword, 1 , -1 , 2 , 75 , 2 , one-handed \\
Longsword002,Longsword, 2 , -1 , 2 , 75 , 2 , two-handed \\
Longsword003,Longsword, 3 , -1 , 2 , 75 , 2 , three-handed \\
\end{filecontents*}

\newcommand{\PrintDTLTable}[2]{%
% #1 = database to search
% #2 = list of rowIDs
\begin{enumerate}
\DTLforeach*[\DTLisSubString{#2}{\RowID}]{#1}{%
    \RowID=RowID,%
    \Label=Label,%
    \Cost=Cost,%
    \Weight=Weight,%
    \Description=Description%
    }{%
    \item \Label ; Price=\Cost ; Weight=\Weight ; It's very \Description
}%
\end{enumerate}
}%

\begin{document}

\DTLloaddb[noheader,keys={RowID,Label,Cost,Weight,PropA,PropB,PropC,Description}]{myDB}{foo.dat}

\PrintDTLTable{myDB}{Hammer001,Hammer003,Longsword003}
\end{document}

命令

\PrintDTLTable{myDB}{Hammer001,Hammer003,Longsword003}

做的正是我想要的,除了

\PrintDTLTable{myDB}{Hammer003,Longsword003,Hammer001}

显然会产生完全相同的结果。

有什么办法可以保持给定的顺序?(抱歉我的英语不好)

答案1

\DTLforeach逐行访问行。因此,数据库的行顺序很重要:

\DTLforeach*[\DTLisSubString{#2}{\RowID}]{#1}{%
 % #2 = list of rowIDs

在以下解决方案中,我将数据提取放在一个 for 循环中,该循环遍历给定的行 ID。有许多 for 循环,例如 LaTeX 的循环\@for。我使用的\comma@parse是来自包 kvsetkeys 的循环,因为它会从列表中的条目中删除前导和尾随空格。然后将行 ID 与行 ID 进行比较\equal以仅获得精确匹配。

\usepackage{kvsetkeys}

\makeatletter
\newcommand{\PrintDTLTable}[2]{%
  % #1 = database to search
  % #2 = list of rowIDs
  \begin{enumerate}
    \comma@parse{#2}{%
      \DTLforeach*[\equal{\comma@entry}{\RowID}]{#1}{%
        \RowID=RowID,%
        \Label=Label,%
        \Cost=Cost,%
        \Weight=Weight,%
        \Description=Description%
      }{%
        \item \Label ; Price=\Cost ; Weight=\Weight ; It's very \Description
        \dtlbreak
      }%
      \@gobble % ignore the entry argument provided by \comma@parse
    }%
  \end{enumerate}
}%
\makeatother

当然,该算法的运行时间表现不佳。对于具有 n 个条目和 m 个选定行的数据库,其时间为 O(n*m)。这意味着如果输出整个数据库,则时间为 O(n²)。理论上,排序可以在 O(n*log(n)) 中完成。

相关内容