我正在努力使用该包从数组中获取数值arrayjobx
。我的目标是将值列表存储在几个数组中,然后在表中显示它们时能够显示总和(每行/列)。我会使用计数器来计算总和,但我无法获取存储在中的数值,array
以便用它来\addtocounter
计算总和。
以下是一个简短的例子:
\documentclass{letter}
\usepackage{arrayjobx}
\begin{document}
\newarray\First
\newarray\Second
\newarray\Third
\readarray{First}{10&8&3}
\readarray{Second}{1&7&8}
\readarray{Third}{1&5&16}
\newcounter{ExpOneTotal}
\begin{tabular}{|c|c|c|c|c|}
\hline
Experiment & a & b & c & TOTAL \\ \hline
Exp 1 & \First(1) & \First(2) & \First(3) & \\
Exp 2 & \Second(1) & \Second(2) & \Second(3) & \\
Exp 3 & \Third(1) & \Third(2) & \Third(3) & \\
TOTAL & & & & \\
\hline
\end{tabular}
\First(1)
\the\numexpr \First(1) \relax
\addtocounter{ExpOneTotal}{\numexpr \First(1) \relax}
My counter is: \theExpOneTotal~ instead of \First(1)
\end{document}
答案1
您可以使用更灵活的方法;arrayjobx
没有必要那么复杂,而且expl3
方法更加强大。
\documentclass{letter}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\setarray}{O{;}mm}
{
\seq_clear_new:c { g_alexb_array_#2_seq }
\seq_gset_split:cnn { g_alexb_array_#2_seq } { #1 } { #3 }
}
\NewDocumentCommand{\getfromarray}{mm}
{
\seq_item:cn { g_alexb_array_#1_seq } { #2 }
}
\cs_generate_variant:Nn \seq_gset_split:Nnn { c }
\cs_set_eq:NN \inteval \int_eval:n
\ExplSyntaxOff
\newcounter{ExpOneTotal}
\begin{document}
\setarray{First}{10;8;3}
\setarray{Second}{1;7;8}
\setarray{Third}{1;5;16}
\begin{tabular}{|c|c|c|c|c|}
\hline
Experiment & a & b & c & TOTAL \\ \hline
Exp 1 & \getfromarray{First}{1} & \getfromarray{First}{2} & \getfromarray{First}{3} & \\
Exp 2 & \getfromarray{Second}{1} & \getfromarray{Second}{2} & \getfromarray{Second}{3} & \\
Exp 3 & \getfromarray{Third}{1} & \getfromarray{Third}{2} & \getfromarray{Third}{3} & \\
TOTAL & & & & \\
\hline
\end{tabular}
\getfromarray{First}{1}
\the\numexpr \getfromarray{First}{1} \relax
\addtocounter{ExpOneTotal}{\numexpr \getfromarray{First}{1} \relax}
My counter is \theExpOneTotal{}; should be \getfromarray{First}{1}.
\setcounter{ExpOneTotal}{%
\inteval{
\getfromarray{First}{1}+
\getfromarray{Second}{1}+
\getfromarray{Third}{1}
}
}
My counter is \theExpOneTotal{}; should be
\inteval{
\getfromarray{First}{1}+
\getfromarray{Second}{1}+
\getfromarray{Third}{1}
}
\end{document}
如您所见,\inteval
您甚至不需要设置计数器,因为可以即时进行计算。
在\setarray
命令中,分隔符是可自定义的,您可以执行
\setarray[&]{First}{10&8&3}
如果您愿意的话(甚至可以将标记更改为O
参数的默认值)。
您甚至可以使用浮点值,而不是\fpeval
(\inteval
需要加载xfp
包)。
答案2
\First
不可扩展,因此不能在中使用\numexpr
。包arrayjobx
提供以下替代方案:
\check<arrayname>
提取所需的值并将其存储在现在可以在其他地方\cachedata
使用:\numexpr
\documentclass{letter}
\usepackage{arrayjobx}
\begin{document}
\newarray\First
\readarray{First}{10&8&3}
\newcounter{ExpOneTotal}
\First(1)
\checkFirst(1)\cachedata~=~\the\numexpr\cachedata\relax
\addtocounter{ExpOneTotal}{\cachedata}
My counter is: \theExpOneTotal~=~\First(1)
\end{document}
计算行和列的总和:
\documentclass{letter}
\usepackage{arrayjobx}
\usepackage{booktabs}
\begin{document}
\newarray\First
\newarray\Second
\newarray\Third
\readarray{First}{10&8&3}
\readarray{Second}{1&7&8}
\readarray{Third}{1&5&16}
\newcounter{ExpTotali}
\newcounter{ExpTotalii}
\newcounter{ExpTotaliii}
\def\AddTotal#1(#2){%
\csname check#1\endcsname({#2})%
\cachedata
\addtocounter{ExpTotal\romannumeral#2}\cachedata
}
\newcounter{ExpTotalSum}
\newcounter{ExpSum}
\makeatletter
\def\ExpSum#1(#2){%
\setcounter{ExpSum}{0}%
\begingroup
\@for\I:=#2\do{%
\csname check#1\endcsname(\I)%
\addtocounter{ExpSum}{\cachedata}%
}%
\endgroup
\theExpSum
\addtocounter{ExpTotalSum}{\value{ExpSum}}%
}
\makeatother
\begin{tabular}{ccccc}
\toprule
Experiment & a & b & c & TOTAL \\
\midrule
Exp 1 & \AddTotal{First}(1) & \AddTotal{First}(2) & \AddTotal{First}(3) &
\ExpSum{First}(1,2,3) \\
Exp 2 & \AddTotal{Second}(1) & \AddTotal{Second}(2) & \AddTotal{Second}(3) &
\ExpSum{Second}(1,2,3) \\
Exp 3 & \AddTotal{Third}(1) & \AddTotal{Third}(2) & \AddTotal{Third}(3) &
\ExpSum{Third}(1,2,3) \\
\midrule
TOTAL & \theExpTotali & \theExpTotalii & \theExpTotaliii &
\theExpTotalSum \\
\bottomrule
\end{tabular}
\end{document}
通过包对数字进行对齐siunitx
:
\documentclass{letter}
\usepackage{arrayjobx}
\usepackage{booktabs}
\usepackage{siunitx}
\begin{document}
\newarray\First
\newarray\Second
\newarray\Third
\readarray{First}{10&8&3}
\readarray{Second}{1&7&8}
\readarray{Third}{1&5&16}
\newcounter{ExpTotali}
\newcounter{ExpTotalii}
\newcounter{ExpTotaliii}
\def\AddTotal#1(#2){%
\csname check#1\endcsname({#2})%
\addtocounter{ExpTotal\romannumeral#2}\cachedata
\global\let\CD\cachedata
}
\newcounter{ExpTotalSum}
\newcounter{ExpSum}
\makeatletter
\def\ExpSum#1(#2){%
\setcounter{ExpSum}{0}%
\begingroup
\@for\I:=#2\do{%
\csname check#1\endcsname(\I)%
\addtocounter{ExpSum}{\cachedata}%
}%
\endgroup
\addtocounter{ExpTotalSum}{\value{ExpSum}}%
}
\makeatother
\begin{tabular}{c*{4}{S[table-format=2]}}
\toprule
Experiment & a & b & c & TOTAL \\
\midrule
Exp 1
& {\AddTotal{First}(1)}\CD
& {\AddTotal{First}(2)}\CD
& {\AddTotal{First}(3)}\CD
& {\ExpSum{First}(1,2,3)}\theExpSum \\
Exp 2
& {\AddTotal{Second}(1)}\CD
& {\AddTotal{Second}(2)}\CD
& {\AddTotal{Second}(3)}\CD
& {\ExpSum{Second}(1,2,3)}\theExpSum \\
Exp 3
& {\AddTotal{Third}(1)}\CD
& {\AddTotal{Third}(2)}\CD
& {\AddTotal{Third}(3)}\CD
& {\ExpSum{Third}(1,2,3)}\theExpSum \\
\midrule
TOTAL & \theExpTotali & \theExpTotalii & \theExpTotaliii &
\theExpTotalSum \\
\bottomrule
\end{tabular}
\end{document}