如何转换数据类型?

如何转换数据类型?

我正在尝试使用 datatools\DTLfetch从 .csv 文件加载的数据库中获取一个实数,然后将这个数字参数传递给\FPeval

问题是它\DTLfetch似乎总是返回一个字符串而不是数字,这会导致错误,因为 FP 无法处理字符串数据类型。

\DTLgetvalue总是返回所需的数字数据类型并且一切正常,但是,我确实需要\DTLfetch

过去两天我一直在尝试弄清楚如何在 LaTeX 中将字符串转换为数字数据类型,或者如何返回\DTLfetch数字值而不是字符串。

LaTeX 在这方面的能力是否严重不足?还是我遗漏了某些基本的东西?我应该使用 Sagetex 进行转换吗?

非常感谢!

答案1

TeX 是一种宏语言,除了字符串之外没有其他类型。(有类型寄存器,但与此无关)问题不在于\DTLfetch“返回”字符串,而在于它\DTLfetch不可扩展。

不可扩展的宏例如\DTLfetch不会扩展为值,但有时它们会在当前列表中插入一些结果。这就是为什么您可以在文档中使用查看结果DTLfetch,但在内部不起作用的原因\FPeval

为了解决这个问题,你可以使用egreg 编写的\DTLfetchsave变体\DTLfetch检索 `\DTLfetch` 的子字符串它将结果保存在一个新的宏中,然后可以将其扩展(类似于\FPeval其自身):

\begin{filecontents*}{students.csv}
name,grade
Joe Bloggs,2.7
Jane Doe,1.0
John Smith,3.0
\end{filecontents*}

\documentclass{article}
\usepackage{datatool,fp}

% From egreg at https://tex.stackexchange.com/questions/335483/retrieving-substring-of-dtlfetch
\newcommand{\DTLfetchsave}[5]{%
  \edtlgetrowforvalue{#2}{\dtlcolumnindex{#2}{#3}}{#4}%
  \dtlgetentryfromcurrentrow{\dtlcurrentvalue}{\dtlcolumnindex{#2}{#5}}%
  \let#1\dtlcurrentvalue
}

\begin{document}
  \DTLloaddb{students}{students.csv}
  \DTLfetchsave\grade{students}{name}{Jane Doe}{grade}
  \FPeval\doublegrade{2*\grade}
  \doublegrade
\end{document}

答案2

当我尝试使用 (CSV) 数据库中的数据通过 TikZ/PGFPlots 绘制单个值或使用 siunitx 打印值时,我遇到了同样的问题。

在发布后我发现了如何将数据库中的所有值存储为以相应键命名的(扩展的)LaTeX 变量:

\documentclass[tikz]{standalone}
\usepackage{siunitx}
\usepackage{filecontents}
\begin{filecontents*}{mydb.csv}
key;value
mykey;1.0
\end{filecontents*}

% Relevant code below
\usepackage{datatool}
\DTLsetseparator{;}
\DTLloaddb{mydb}{mydb.csv}

\begin{document}
\DTLforeach{mydb}{\Key=key,\Value=value}
{%
   \cslet{\Key}{\Value}%
}
\DTLfetch{mydb}{key}{mykey}{value} works\\
% while $\num{\DTLfetch{mydb}{key}{mykey}{value}}$ fails
\mykey prints the value for mykey, $\num{\mykey}$ also works
\end{document}

但是,加载具有相似键的多个数据库会重新分配相同的变量。

作为一个快速修复,我将DTLFetch值分配给以数据库名称和键的连接命名的变量,并编写了一个函数来解析后者:

\documentclass[tikz]{standalone}
\usepackage{siunitx}
\usepackage{filecontents}
\begin{filecontents*}{mydb.csv}
key;value
mykey;1.0
\end{filecontents*}

% Relevant code below
\usepackage{datatool}
\DTLsetseparator{;}
\DTLloaddb{mydb}{mydb.csv}

\newcommand{\getval}[2]{\csname#1#2\endcsname}

\begin{document}
\DTLforeach{mydb}{\Key=key,\Value=value}
{%
   \cslet{mydb\Key}{\Value}%
}
\getval{mydb}{mykey} prints the value for mykey, $\num{\getval{mydb}{mykey}}$ also works
\end{document}

答案3

我还发现, \xDTLassignfirstmatchdatatool的工作原理似乎与相同\DTLfetch,但具有扩展,并且对我来说效果很好!

相关内容