从数据工具数据库中获取多个特定列的唯一值

从数据工具数据库中获取多个特定列的唯一值

如何获取 datatool 数据库中特定列的所有不同值以及另一列中的对应值?在下面的示例中,我想要获取输出:

数据库中 Xland 的城市是 Xcity
数据库中 Yland 的城市是 Ycity
数据库中 Zland 的城市是 Zcity

我知道我可以获取如下例所示的唯一城市列表(类似地,唯一国家列表)但我该如何将它们结合起来?

\documentclass{article}

\usepackage{etoolbox}
\usepackage{datatool}

\begin{filecontents}{test.csv}
Name,Town,Country,Age
Adam,Xcity,Xland,20
Berta,Ytown,Yland,30
Cesar,Ztington,Zland,40
Dora,Ztington,Zland,20
Emil,Ytown,Yland,30
Franz,Ytown,Yland,20
\end{filecontents}

\DTLloaddb{data}{test.csv}

\begin{document}

\newcommand*{\uniquetowns}{}
\newcommand*{\uniquecountries}{}

\DTLforeach*{data}{\Town=Town,\uniquecountries=Country}{%
  \expandafter\DTLifinlist\expandafter{\Town}{\uniquetowns}%
  {}% do nothing, already in list
  {% add to list
    \ifdefempty{\uniquetowns}%
    {\let\uniquetowns\Town}% first element of list
    {% append to list
      \eappto\uniquetowns{,\Town}%
    }%
  }%
}

List of unique towns: \uniquetowns.


\end{document}

相关问题:获取数据工具数据库中特定列的所有不同值

答案1

我可能不太明白你想要实现什么,但是这样怎么样?

\documentclass{article}
\usepackage{datatool}

\begin{filecontents}{test.csv}
Name,Town,Country,Age
Adam,Xcity,Xland,20
Berta,Ytown,Yland,30
Cesar,Ztington,Zland,40
Dora,Ztington,Zland,20
Emil,Ytown,Yland,30
Franz,Ytown,Yland,20
\end{filecontents}

\DTLloaddb{data}{test.csv}

\begin{document}

\newcommand*{\uniquetowns}{}
% \newcommand*{\uniquecountries}{}

\DTLforeach*{data}{\Town=Town, \Country=Country}{%
  \expandafter\DTLifinlist\expandafter{\Town}{\uniquetowns}%
  {}% do nothing, already in list
  {% add to list
    \ifdefempty{\uniquetowns}%
    {\let\uniquetowns\Town}% first element of list
    {% append to list
      \eappto\uniquetowns{,\Town}%
    }%
    A city of \Country{} in the database is \Town . 
  }%
}

\end{document}

这将针对每个不同的城镇输出:

在此处输入图片描述

但是,在您的示例中,城镇和国家的名称是这样选择的:每个城镇只能位于特定国家,每个国家只能与一个特定城镇相关。您是否需要处理两个同名城镇可能位于不同国家的情况?

如果是这种情况,您可以将每个条目的国家和城镇名称合并起来,以创建唯一的国家城镇条目。这样,您就可以保证获得每个国家的每个城镇。(请注意,我不得不更改一些宏才能处理组合字符串。)

\documentclass{article}
\usepackage{datatool}

\begin{filecontents}{test.csv}
Name,Town,Country,Age
Adam,Rome,Italy,20
Berta,Rome,U.S.,30
Cesar,Berlin,Germany,40
Dora,Munich,Germany,20
Emil,New York,U.S.,30
Franz,Milan,Italy,20
Gustav,Milan,Italy,20
Heinrich,Rome,Italy,20
\end{filecontents}

\DTLloaddb{data}{test.csv}

\begin{document}

\newcommand*{\uniquetowns}{}
%\newcommand*{\uniquecountries}{}

\noindent%
\DTLforeach*{data}{\Town=Town, \Country=Country}{%
  \DTLifSubString{\uniquetowns}{\Town.\Country}%
  {}% do nothing, already in list
  {% add to list
    \ifdefempty{\uniquetowns}%
    {% first element of list
        \eappto\uniquetowns{\Town.\Country}%
    }%
    {% append to list
        \eappto\uniquetowns{,\Town.\Country}%
    }%
    A city of \Country{} in the database is \Town . \\
  }%
}

\end{document}

输出为:

在此处输入图片描述

如您所见,意大利和美国的罗马都在考虑之列,德国的慕尼黑和柏林也在考虑之列。不过,这份名单还是很独特的,因为罗马(意大利)和米兰(意大利)都只上榜一次。


更新

由于原帖作者表示他们想要一个结果,即所有属于一个国家的城镇都合并在一个句子中,所以我又试了一次。但是,要做到这一点,\DTLforeach需要多个实例。因此,如果有大量数据需要继续,则需要一些时间。

\documentclass{article}
\usepackage{datatool}

\begin{filecontents}{test.csv}
Name,Town,Country,Age
Adam,Rome,Italy,20
Berta,Rome,U.S.,30
Cesar,Berlin,Germany,40
Dora,Munich,Germany,20
Emil,New York,U.S.,30
Franz,Milan,Italy,20
Gustav,Milan,Italy,20
Heinrich,Rome,Italy,20
\end{filecontents}

\DTLloaddb{data}{test.csv}

\DTLnewdb{countries}
\newcommand*{\uniquecountries}{}
\newcommand*{\uniquetowns}{}
\newcommand*{\countrysentence}{}

\begin{document}

% first, generate database with unique entries
\DTLforeach*{data}{\Country=Country}{%
  \DTLifSubString{\uniquecountries}{\Country}%
  {% do nothing, already in list
  }%
  {% add to list
    \DTLnewrow{countries}%
    {\dtlexpandnewvalue\DTLnewdbentry{countries}{Country}{\Country}}%
    \eappto\uniquecountries{\Country : }%
  }%
}%

\noindent%
\DTLforeach*{countries}{\CurrentCountry=Country}{%
  \renewcommand{\uniquetowns}{}%
  \renewcommand{\countrysentence}{}%
  \DTLforeach*[\DTLiseq{\CurrentCountry}{\Country}]{data}%
  {\Country=Country, \Town=Town}{%
    \DTLifSubString{\uniquetowns}{\Town}%
    {% do nothing, already in list
    }%
    {% add to list
      \eappto\uniquetowns{\Town : }%
      \ifdefempty{\countrysentence}%
      {% first element of list
        \eappto\countrysentence{The cities in \CurrentCountry{} are \Town}%
      }%
      {% append to list
        \eappto\countrysentence{, \Town}%
      }%
    }%
  }%
  \eappto\countrysentence{.}%
  \countrysentence \\
}

\end{document}

输出:

在此处输入图片描述

也许这可以更轻松地实现,但我找不到任何更简单的解决方案。有两个问题导致了这种特定的设置:首先,除了通过另一个存储列表的宏之外,没有其他方法可以仅过滤唯一数据;其次,据我所知,您无法轻松读取存储在宏中的数据\DTLforeach。因此,我需要创建一个存储在宏中的列表以及一个数据库,这似乎有点麻烦。但也许我错了。

相关内容