我如何计算值的数量并使用它来创建正确的列数

我如何计算值的数量并使用它来创建正确的列数

根据 egreg 对我的第一个问题的回答(再次感谢他) 这里,我尝试了以下方法在水平和垂直函数表之间切换。这似乎工作正常(脏代码)。但在水平模式下,我必须在 #4 处的宏 \functiontabT 中给出列表中的值的数量。

我的问题是,如何自动计算值的数量并用它来创建表中的列数。

感谢您的帮助

在此处输入图片描述

\documentclass{article}
\usepackage{xparse}
\usepackage{xintexpr}
\usepackage{siunitx}

\ExplSyntaxOn
\NewDocumentCommand{\functiontableV}{mmO{2}}
 {% #1 = list of values, #2 = function, #3 = number of decimal digits
  \thomas_functiontable:nnn { #1 } { #2 } { #3 }
 }
\seq_new:N \__thomas_functiontable_rows_seq
\cs_new_protected:Nn \thomas_functiontable:nnn
 {
  \cs_set:Nn \__thomas_functiontable_function:n  { #2 }
  \seq_clear:N \l__thomas_functiontable_rows_seq
  \clist_map_inline:nn { #1 }
   {
    \seq_put_right:Nx \l__thomas_functiontable_rows_seq
     {
     \num{ ##1 } & \num{ \fp_eval:n { round( \__thomas_functiontable_function:n { ##1 }, #3 ) } }
     } 
   }
  \seq_use:Nn \l__thomas_functiontable_rows_seq { \\ }
}
\ExplSyntaxOff

\ExplSyntaxOn
\NewDocumentCommand{\functiontab}{mmO{2}}{% #1 = list of values, #2 = function, #3 = number of decimal digits
  \thomas_functiontab:nnn { #1 } { #2 } { #3 } }

\seq_new:N \__thomas_functiontab_rows_seq
\cs_new_protected:Nn \thomas_functiontab:nnn
 {
  \cs_set:Nn \__thomas_functiontab_function:n  { #2 }
  \seq_clear:N \l__thomas_functiontab_rows_seq
  \clist_map_inline:nn { #1 }
   {
    \seq_put_right:Nx \l__thomas_functiontab_rows_seq
     {
     & \num{ ##1 } 
     }
   }
   \seq_use:Nn \l__thomas_functiontab_rows_seq {}
}

\NewDocumentCommand{\functiontabB}{mmO{2}}{% #1 = list of values, #2 = function, #3 = number of decimal digits
  \thomas_functiontabB:nnn { #1 } { #2 } { #3 } }

\seq_new:N \__thomas_functiontabB_rows_seq
\cs_new_protected:Nn \thomas_functiontabB:nnn
 {
  \cs_set:Nn \__thomas_functiontabB_function:n  { #2 }
  \seq_clear:N \l__thomas_functiontabB_rows_seq
  \clist_map_inline:nn { #1 }
   {
    \seq_put_right:Nx \l__thomas_functiontabB_rows_seq
     {
     & \num{ \fp_eval:n { round( \__thomas_functiontabB_function:n { ##1 }, #3 ) } }
     }
   }
 \seq_use:Nn \l__thomas_functiontabB_rows_seq {}
}
\ExplSyntaxOff

\NewDocumentCommand{\functiontabT}{mmO{2}mmmO{$x$}D(){$f(x)$}t{!}}{%% #1 = list of values, #2 = function, #3 = number of decimal digits
% #4 = Number of columns, #5 = width column 1, #6 = width column 2 and all others in horizontal, #7 = name x, #8 = name f(x), #9 = ! switch horizontal - vertical
\IfBooleanTF{#9}{%
\begin{tabular}{>{\centering\arraybackslash}p{#5}|>{\centering\arraybackslash}p{#6}}
  {#7} & {#8} \\\hline
  \functiontableV{#1}{#2}[#3]
\end{tabular}
}{%
\begin{tabular}{>{\centering\arraybackslash}p{#5}*{#4}{|>{\centering\arraybackslash}p{#6}}}
#7 \functiontab{#1}{#2}[#3] \\ \hline
#8 \functiontabB{#1}{#2}[#3]
\end{tabular}
}
}

\begin{document}

\functiontabT{1, 2, 3.5, 4, 6,100,200}{ ln(#1^3+13) }[2]{7}{1cm}{0.8cm}[a](b)

\bigskip

\functiontabT{1, 2, 3.5, 4,11,14,300,500}{ ln(\xinttheexpr #1! \relax) }[2]{8}{1cm}{1.4cm}!

\bigskip

\functiontabT{0, 30, 45, 60, 90}{ sind(#1) }[5]{7}{1cm}{1.6cm}!

\end{document} 

答案1

这是水平表和垂直表的实现。

\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx}
\usepackage{array}

\ExplSyntaxOn

\NewDocumentCommand{\functiontable}{O{}mm}
 {% #1 = option list, #2 = list of values, #3 = function
  \group_begin:
  \keys_set:nn { thomas/functiontable } { #1 }
  \bool_if:NTF \l__thomas_functiontable_hor_bool
   {
    \thomas_functiontable_hor:nn { #2 } { #3 }
   }
   {
    \thomas_functiontable_vert:nn { #2 } { #3 }
   }
  \group_end:
 }

\seq_new:N \__thomas_functiontable_rows_seq
\seq_new:N \__thomas_functiontable_row_one_seq
\seq_new:N \__thomas_functiontable_row_two_seq
\seq_new:N \l__thomas_functiontable_columns_seq

\keys_define:nn { thomas/functiontable }
 {
  hor   .bool_set:N = \l__thomas_functiontable_hor_bool,
  hor   .initial:n  = false,
  hor   .default:n  = true,
  round .int_set:N = \l__thomas_functiontable_round_int,
  round .initial:n = 2,
  ivar  .tl_set:N  = \l__thomas_functiontable_ivar_tl,
  ivar  .initial:n = x,
  dvar  .tl_set:N  = \l__thomas_functiontable_dvar_tl,
  dvar  .initial:n = f(x),
  align .tl_set:N  = \l__thomas_functiontable_align_tl,
  align .initial:n = c,
  cols  .tl_set:N  = \l__thomas_functiontable_make_columns_tl,
 }

\cs_new_protected:Nn \thomas_functiontable_vert:nn
 {
  \cs_set:Nn \__thomas_functiontable_function:n  { #2 }
  \seq_clear:N \l__thomas_functiontable_rows_seq
  \clist_map_inline:nn { #1 }
   {
    \seq_put_right:Nx \l__thomas_functiontable_rows_seq
     {
      ##1
      &
      \exp_not:N \__thomas_functiontable_num:n
       {
        \fp_eval:n
         {
          round( \__thomas_functiontable_function:n { ##1 }, \l__thomas_functiontable_round_int )
         }
       }
     }
   }
  \__thomas_functiontable_make_columns_vert:
  \use:x
   {
    \exp_not:N \begin{tabular}
    [\l__thomas_functiontable_align_tl]
    {\exp_not:V \l__thomas_functiontable_columns_tl}
   }
  $\l__thomas_functiontable_ivar_tl$ & $\l__thomas_functiontable_dvar_tl$ \\
  \hline
  \seq_use:Nn \l__thomas_functiontable_rows_seq { \\ }
  \end{tabular}
}

\cs_new_protected:Nn \__thomas_functiontable_make_columns_vert:
 {
  \tl_if_in:NnTF \l__thomas_functiontable_make_columns_tl { S }
   {
    \cs_set_eq:NN \__thomas_functiontable_num:n \use:n
   }
   {
    \cs_set_eq:NN \__thomas_functiontable_num:n \num
   }
  \tl_if_empty:NTF \l__thomas_functiontable_make_columns_tl
   {
    \tl_set:Nn \l__thomas_functiontable_columns_tl { c | c }
   }
   {
    \seq_set_split:NnV \l__thomas_functiontable_columns_seq { | } \l__thomas_functiontable_make_columns_tl
    \int_compare:nTF { \seq_count:N \l__thomas_functiontable_columns_seq <= 1 }
     {
      \tl_set:Nx \l__thomas_functiontable_columns_tl
       {
        \l__thomas_functiontable_make_columns_tl | \l__thomas_functiontable_make_columns_tl
       }
     }
     {
      \tl_set:Nx \l__thomas_functiontable_columns_tl
       {
        \seq_item:Nn \l__thomas_functiontable_columns_seq { 1 }
        |
        \seq_item:Nn \l__thomas_functiontable_columns_seq { 2 }
       }
     }
   }
 }

\cs_new_protected:Nn \thomas_functiontable_hor:nn
 {
  \cs_set:Nn \__thomas_functiontable_function:n  { #2 }
  \seq_clear:N \l__thomas_functiontable_row_one_seq
  \seq_clear:N \l__thomas_functiontable_row_two_seq
  \clist_map_inline:nn { #1 }
   {
    \seq_put_right:Nn \l__thomas_functiontable_row_one_seq { \num{##1} }
    \seq_put_right:Nx \l__thomas_functiontable_row_two_seq
     {
      \num
       {
        \fp_eval:n
         {
          round( \__thomas_functiontable_function:n { ##1 }, \l__thomas_functiontable_round_int )
         }
       }
     }
   }
  \__thomas_functiontable_make_columns_hor:
  \use:x
   {
    \exp_not:N \begin{tabular}
    [\l__thomas_functiontable_align_tl]
    {\exp_not:V \l__thomas_functiontable_columns_tl}
   }
  $\l__thomas_functiontable_ivar_tl$ & \seq_use:Nn \l__thomas_functiontable_row_one_seq { & }
  \tabularnewline
  \hline
  $\l__thomas_functiontable_dvar_tl$ & \seq_use:Nn \l__thomas_functiontable_row_two_seq { & }
  \end{tabular}
 }

\cs_new_protected:Nn \__thomas_functiontable_make_columns_hor:
 {
  \tl_if_empty:NTF \l__thomas_functiontable_make_columns_tl
   {
    \tl_set:Nx \l__thomas_functiontable_columns_tl
     {
      c
      *{\seq_count:N \l__thomas_functiontable_row_one_seq}{|c}
     }
   }
   {
    \seq_set_split:NnV \l__thomas_functiontable_columns_seq { | } \l__thomas_functiontable_make_columns_tl
    \int_compare:nTF { \seq_count:N \l__thomas_functiontable_columns_seq <= 1 }
     {
      \tl_set:Nx \l__thomas_functiontable_columns_tl
       {
        \l__thomas_functiontable_make_columns_tl
        *{\seq_count:N \l__thomas_functiontable_row_one_seq}{|\l__thomas_functiontable_make_columns_tl}
       }
     }
     {
      \tl_set:Nx \l__thomas_functiontable_columns_tl
       {
        \seq_item:Nn \l__thomas_functiontable_columns_seq { 1 }
        *{\seq_count:N \l__thomas_functiontable_row_one_seq}
         {
          |\seq_item:Nn \l__thomas_functiontable_columns_seq { 2 }
         }
       }
     }
   }
 }

\ExplSyntaxOff

\begin{document}

X \functiontable[hor]{1, 2, 3.5, 4}{ #1^2+3 } Y

\bigskip

X \functiontable[hor,cols=c|>{\centering}p{2cm}]{1, 2, 3.5, 4}{ #1^2+3 } Y

\bigskip

X \functiontable[
  round=5,
  ivar=a,
  dvar=b,
  align=t,
  cols={ S[table-format=2.0] | S[table-format=1.5] },
]{0, 30, 45, 60, 90}{ sind(#1) } Y

\end{document} 

在此处输入图片描述

答案2

我发现

\clist_count:n { #1 }

这个有效。

\documentclass{article}
\usepackage{xparse}
\usepackage{xintexpr}
\usepackage{siunitx}
\sisetup{group-separator={\,},output-decimal-marker={,}}

\ExplSyntaxOn
\NewDocumentCommand{\functiontableV}{mmO{2}}
 {% #1 = list of values, #2 = function, #3 = number of decimal digits
  \thomas_functiontable:nnn { #1 } { #2 } { #3 }
 }
\seq_new:N \__thomas_functiontable_rows_seq
\cs_new_protected:Nn \thomas_functiontable:nnn
 {
  \cs_set:Nn \__thomas_functiontable_function:n  { #2 }
  \seq_clear:N \l__thomas_functiontable_rows_seq
  \clist_map_inline:nn { #1 }
   {
    \seq_put_right:Nx \l__thomas_functiontable_rows_seq
     {
     \num{ ##1 } & \num{ \fp_eval:n { round( \__thomas_functiontable_function:n { ##1 }, #3 ) } }
     } 
   }
  \seq_use:Nn \l__thomas_functiontable_rows_seq { \\ }
}

\NewDocumentCommand{\functiontab}{mmO{2}}{% #1 = list of values, #2 = function, #3 = number of decimal digits
  \thomas_functiontab:nnn { #1 } { #2 } { #3 } }

\seq_new:N \__thomas_functiontab_rows_seq
\cs_new_protected:Nn \thomas_functiontab:nnn
 {
  \cs_set:Nn \__thomas_functiontab_function:n  { #2 }
  \seq_clear:N \l__thomas_functiontab_rows_seq
  \clist_map_inline:nn { #1 }
   {
    \seq_put_right:Nx \l__thomas_functiontab_rows_seq
     {
     & \num{ ##1 } 
     }
   }
   \seq_use:Nn \l__thomas_functiontab_rows_seq {}
}

\NewDocumentCommand{\functiontabB}{mmO{2}}{% #1 = list of values, #2 = function, #3 = number of decimal digits
  \thomas_functiontabB:nnn { #1 } { #2 } { #3 } }

\seq_new:N \__thomas_functiontabB_rows_seq
\cs_new_protected:Nn \thomas_functiontabB:nnn
 {
 \def\AnzahlderElemente{\clist_count:n { #1 }}
  \cs_set:Nn \__thomas_functiontabB_function:n  { #2 }
  \seq_clear:N \l__thomas_functiontabB_rows_seq
  \clist_map_inline:nn { #1 }
   {
    \seq_put_right:Nx \l__thomas_functiontabB_rows_seq
     {
     & \num{ \fp_eval:n { round( \__thomas_functiontabB_function:n { ##1 }, #3 ) } }
     }
   }
 \seq_use:Nn \l__thomas_functiontabB_rows_seq {}
}


\NewDocumentCommand{\functiontabT}{mmO{2}mmO{$x$}D(){$f(x)$}t{!}}{%% #1 = list of values, #2 = function, #3 = number of decimal digits
% #4 = width column 1, #5 = width column 2 and all others in horizontal, #6 = name x, #7 = name f(x), #8 = ! switch horizontal - vertical
\IfBooleanTF{#8}{%
\begin{tabular}{>{\centering\arraybackslash}p{#4}|>{\centering\arraybackslash}p{#5}}
  {#6} & {#7} \\\hline
  \functiontableV{#1}{#2}[#3]
\end{tabular}
}{%
\begin{tabular}{>{\centering\arraybackslash}p{#4}*{\clist_count:n { #1 }}{|>{\centering\arraybackslash}p{#5}}}
#6 \functiontab{#1}{#2}[#3] \\ \hline
#7 \functiontabB{#1}{#2}[#3]
\end{tabular}
}
}
\ExplSyntaxOff
\begin{document}

\functiontabT{1, 2, 3.5, 4, 6,100,200,300,30}{ ln(#1^3+13) }[2]{1cm}{0.8cm}[a](b)

\bigskip

\functiontabT{1, 2, 3.5, 4,11,14,300,500}{ ln(\xinttheexpr #1! \relax) }[2]{1cm}{1.4cm}!

\bigskip

\functiontabT{0, 30, 45, 60, 90}{ sind(#1) }[5]{0.8cm}{1.3cm}

\end{document} 

相关内容