过滤 datatool 数据库中的重复项

过滤 datatool 数据库中的重复项

我只想过滤给定数据库中的重复项并将其删除。在我的特定情况下,数据库是从外部.csv数据加载的,并且只有一个列。但为了在这个 MWE 中保持简单,我只是创建了数据库floorRawData并用一些数据填充它。

因为我没有找到任何现成的删除重复项的功能,所以我自己尝试了如下方法:

\documentclass{article}
\usepackage{datatool}

\begin{document}
\DTLnewdb{floorFilteredData}
\DTLnewdb{floorRawData}

\DTLnewrow{floorRawData}
\DTLnewdbentry{floorRawData}{FloorRaw}{groundFloor}
\DTLnewrow{floorRawData}
\DTLnewdbentry{floorRawData}{FloorRaw}{upperFloor}
\DTLnewrow{floorRawData}
\DTLnewdbentry{floorRawData}{FloorRaw}{groundFloor}
\DTLnewrow{floorRawData}
\DTLnewdbentry{floorRawData}{FloorRaw}{basementFloor}
\DTLdisplaydb{floorRawData}\\ % Result as expected!

\newcommand{\noDBentry}{FALSE}

\DTLforeach*{floorRawData}{\floorRaw=FloorRaw}
{
    \noindent FloorRaw Element: \floorRaw\\
    \DTLifdbempty{floorFilteredData}
    {
        \DTLnewrow{floorFilteredData}
        \DTLnewdbentry{floorFilteredData}{FloorFiltered}{\floorRaw}
        \\\DTLdisplaydb{floorFilteredData}\\[5mm]
    }
    {
        \DTLforeach{floorFilteredData}{\floorFiltered=FloorFiltered}
        {
            FloorFiltered Element: \floorFiltered\\ % Why is this element "upperFloor" and not "groundFloor"?
            \ifthenelse{\equal{\floorRaw}{\floorFiltered}}
            {
                \renewcommand{\noDBentry}{TRUE}
            }{}
        }
        \ifthenelse{\equal{\noDBentry}{FALSE}}
        {
            Add new data: \floorFiltered % Never called!
            \DTLnewrow{floorFilteredData}
            \DTLnewdbentry{floorFilteredData}{FloorFiltered}{\floorRaw}
        }
        {
            \renewcommand{\noDBentry}{FALSE}
        }  
    }
}

\DTLdisplaydb{floorFilteredData}\\

\end{document}

在这个 MWE 中,我只是解析floorRawData数据库并检查当前元素是否已经是我的floorFilteredData数据库的一部分。如果它是一部分,那么我不会在floorFilteredData数据库中添加新元素,否则我想添加这个元素。

所以最后我期望一个floorFilteredData数据库,其中每一行都是不同的\floorFiltered元素。

但正如您所见,\floorFiltered元素似乎始终是相同的元素\floorRaw

因此我的预期是,这\DTLforeach{floorFilteredData}{\floorFiltered=FloorFiltered}不会从头开始。

我看了一下 datatool 包手册第 58 页https://texdoc.org/serve/datatool/0但我没有从中得到正确的线索......

嵌套 \foreach

输出 在此处输入图片描述

答案1

经过几个小时的搜索,我发现了这个很棒的常问问题来自 datatool 包维护者 Nicola LC Talbot :) 我想在包装手册在第43页。

\dtlexpandnewvalue解决方案是在以编程方式添加 DB 元素之前进行添加。就是这样!

\documentclass{article}
\usepackage{datatool}

\begin{document}
\DTLnewdb{floorFilteredData}
\DTLnewdb{floorRawData}

\DTLnewrow{floorRawData}
\DTLnewdbentry{floorRawData}{FloorRaw}{groundFloor}
\DTLnewrow{floorRawData}
\DTLnewdbentry{floorRawData}{FloorRaw}{upperFloor}
\DTLnewrow{floorRawData}
\DTLnewdbentry{floorRawData}{FloorRaw}{groundFloor}
\DTLnewrow{floorRawData}
\DTLnewdbentry{floorRawData}{FloorRaw}{basementFloor}
\DTLdisplaydb{floorRawData}\\ % Result as expected!

\newcommand{\noDBentry}{FALSE}
\dtlexpandnewvalue % Just add this line

\DTLforeach*{floorRawData}{\floorRaw=FloorRaw}
{
    \DTLifdbempty{floorFilteredData}
    {
        \DTLnewrow{floorFilteredData}
        \DTLnewdbentry{floorFilteredData}{FloorFiltered}{\floorRaw}
    }
    {
        \DTLforeach{floorFilteredData}{\floorFiltered=FloorFiltered}
        {
            \ifthenelse{\equal{\floorRaw}{\floorFiltered}}
            {
                \renewcommand{\noDBentry}{TRUE}
            }{}
        }
        \ifthenelse{\equal{\noDBentry}{FALSE}}
        {
            \DTLnewrow{floorFilteredData}
            \DTLnewdbentry{floorFilteredData}{FloorFiltered}{\floorRaw}
        }
        {
            \renewcommand{\noDBentry}{FALSE}
        }  
    }
}

\DTLdisplaydb{floorFilteredData}\\

\end{document}

输出 输出

相关内容