我一直在尝试修改解决方案这里进入一个 LaTeX3 命令,该命令采用可变长度的逗号分隔的数字列表和一个可选参数(单位),并打印每个数字的平方和的平方根(如果给定,则连同单位)。
\sumofsquares{2,3,-4}[m/s]
应该给予
但\sumofsquares{3,-4}[m/s]
应该给予
我使用 Google 搜索过 LaTeX3 示例,但找到的示例(和的文档xparse
)expl3
都不包含任何示例。列表和序列之间的差异让我感到困惑。
答案1
这是一个使用序列的选项,它可能会变得更紧凑一些,因为两个辅助宏的代码几乎相同。
我不是专家,所以对我的建议持保留态度,但我会坚持使用sequences
。它们需要一行行额外的代码,但它们提供的额外选项非常值得。
\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx}
\ExplSyntaxOn
\NewDocumentCommand{\sumofsquares}{ m o }
{
\IfNoValueTF {#2}
% if optional is missing call this
{\sum_of_squares:n {#1}}
% if not, then call this
{\sum_of_squares:nn {#1}{#2}}
}
\cs_new_protected:Npn \sum_of_squares:n #1
{
% does what the name suggests, set a sequence from the clist
\seq_set_from_clist:Nn \l_tmpa_seq {#1}
% applies final arg to each element of second seq and stores result in first seq
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq {(##1)^2}
% \seq_use puts the items from the seq back in the input with "+" as a separator
\sqrt{\seq_use:Nnnn \l_tmpb_seq {+}{+}{+}}
}
\cs_new_protected:Npn \sum_of_squares:nn #1 #2
{
% same as above, but with the addition of units
\seq_set_from_clist:Nn \l_tmpa_seq {#1}
\seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq {(\SI{##1}{#2})^2}
\sqrt{\seq_use:Nnnn \l_tmpb_seq {+}{+}{+}}
}
\ExplSyntaxOff
\begin{document}
$\sumofsquares{2,3,-4}$\par\medskip
$\sumofsquares{2,3,-4}[m/s]$
\end{document}
下面是一个使用 s 的略短(且不太清晰)的示例clist
。可以使用相同的方法来缩短上述代码。
\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx}
\ExplSyntaxOn
\NewDocumentCommand{\sumofsquares}{ m O{} }
{
\sum_of_squares:nn {#1}{#2}
}
\cs_new_protected:Npn \sum_of_squares:nn #1 #2
{
\tl_if_empty:nTF {#2}
{
\clist_set:Nn \l_tmpa_clist {#1}
\sqrt{(\clist_use:Nnnn \l_tmpa_clist {)^2+(} {)^2+(} {)^2+(} )^2 }
}
{
\clist_set:Nn \l_tmpa_clist {#1}
\sqrt{(\clist_use:Nnnn \l_tmpa_clist {\,\si{#2})^2+(} {\,\si{#2})^2+(} {\,\si{#2})^2+(} \,\si{#2})^2}
}
}
\ExplSyntaxOff
\begin{document}
$\sumofsquares{2,3,-4}$\par\medskip
$\sumofsquares{2,3,-4}[m/s]$
\end{document}
答案2
嗯,你可以这样做xparse
,所以
$\sumofsquares{2,3,-4}[m/s]$
$\sumofsquares{2,3,-4,4,7}$
产量:
参考:
- 这使用来自的解决方案使用循环为另一个(foreach)循环生成列表来建立序列。
代码:
\documentclass{article}
\usepackage{siunitx}
\usepackage{xparse}
\usepackage{pgffor}
\newcommand{\SequenceOfSquares}{}
\newcommand*{\TermSeparator}{}%
\NewDocumentCommand{\sumofsquares}{m O{}}{%
\gdef\TermSeparator{}% clear up from last use (if any)
\def\Sequence{#1}
\foreach \x in \Sequence {%
\xdef\SequenceOfSquares{\SequenceOfSquares \TermSeparator (\SI{\x}{#2})^2}%
\gdef\TermSeparator{+}%
}
\sqrt{\SequenceOfSquares}%
\gdef\SequenceOfSquares{}%
}
\begin{document}
$\sumofsquares{2,3,-4}[m/s]$
\medskip
$\sumofsquares{2,3,-4,4,7}$
\end{document}
答案3
这是另一个解决方案。不需要解析在这个解决方案中:
\documentclass{article}
\usepackage{siunitx}
\makeatletter
\newcommand\sumofsquares[2][]{%
\def\tempa{}%
\@for\reserved:=#2\do{%
\edef\tempa{\tempa\ifx\tempa\empty\else+\fi(\SI{\reserved}{#1})^2}%
}
\sqrt{\tempa}%
}
\makeatother
\begin{document}
$\sumofsquares[m/s]{2,3,-4}$
\par\medskip
$\sumofsquares{2,3,-4,4,7}$
\end{document}
将可选参数放在最后
这是 OP 的选择;我不推荐它。
\documentclass{article}
\usepackage{siunitx}
\makeatletter
\newcommand*\sumofsquares[1]{\@testopt{\@sumofsquares{#1}}{}}
\def\@sumofsquares#1[#2]{%
\begingroup
\def\tempa{}%
\@for\reserved:=#1\do{%
\edef\tempa{\tempa\ifx\tempa\empty\else+\fi(\SI{\reserved}{#2})^2}%
}
\expandafter\endgroup\expandafter\sqrt\expandafter{\tempa}%
}
\makeatother
\begin{document}
$\sumofsquares{2,3,-4}[m/s]$
\par\medskip
$\sumofsquares{2,3,-4,4,7}$
\end{document}