给定以下矩阵
\def\points{{ {-1, 3}, {2, 7}, {3, 8} }}
对应于 3x2 矩阵
我如何
迭代(在
tikz
)列数?迭代(在
tikz
)行数?直接寻址元素,例如第 1 行、第 0 列(即 2)
关于坐标数组的类似问题在tikz 坐标数组:迭代和寻址元素
答案1
我不确定该函数的当前状态,但有一个未记录的pgfmath
函数dim
,您可以使用它。但请不要在 TikZ 中执行此操作,它没有任何一致性检查,甚至没有数据容器类型。所以这一切都是一厢情愿。相反,要么使用 L3 功能(如果他们不提供答案,请在聊天中惹恼他们!),要么在 TeX 中调用 Lua 或 Python。
TikZ 使用 0 索引,因此-1
在行/列数计算中。
\documentclass{article}
\usepackage{pgfmath, pgffor}
\begin{document}
\def\points{{{-1, 3}, {2, 7}, {3, 8}}}
\pgfmathparse{\points[1][1]}\pgfmathresult% Get 1,1 element
\pgfmathtruncatemacro\myrows{dim(\points)-1}
\pgfmathtruncatemacro\mycols{dim(\points[0])-1}
\foreach\x in{0,...,\myrows}{% Over all rows
\foreach\y in{0,...,\mycols}{% Over all columns
\pgfmathparse{int(\points[\x][\y])}\pgfmathresult,
}%
}
\end{document}
答案2
该listofitems
包可以解析此类列表。
\documentclass{article}
\usepackage{listofitems}
\begin{document}
\setsepchar{;/,}
\readlist\mypoints{-1, 3; 2, 7; 3, 8}
Second row elements are \mypoints[2,1], \mypoints[2,2].
\foreachitem\row\in\mypoints[]{%
\foreachitem\col\in\mypoints[\rowcnt]{%
Row \rowcnt, Column \colcnt{} is $\mypoints[\rowcnt,\colcnt]$\par
}
}
\end{document}
如果有要求\points
按照OP描述的方式嵌套,则需要额外解包才能\reduce
\points
进入\tmp
,其形式如上例所示:
\documentclass{article}
\usepackage{listofitems}
\def\reduce#1{\expandafter\reduceaux#1,\relax}
\def\reduceaux#1,#2\relax{\reduceauxaux#1%
\ifx\relax#2\relax\else;\reduceaux#2\relax\fi%
}
\def\reduceauxaux#1{\reduceauxauxaux#1}
\def\reduceauxauxaux#1,#2{#1,#2}
\begin{document}
\def\points{{ {-1, 3}, {2, 7}, {3, 8} }}
\edef\tmp{\expandafter\reduce\points}
\detokenize\expandafter{\tmp}% THIS SHOWS CONVERSION OF \points INTO \tmp
\setsepchar{;/,}
\readlist\mypoints{\tmp}
Second row elements are \mypoints[2,1], \mypoints[2,2].
\foreachitem\row\in\mypoints[]{%
\foreachitem\col\in\mypoints[\rowcnt]{%
Row \rowcnt, Column \colcnt{} is $\mypoints[\rowcnt,\colcnt]$\par
}
}
\end{document}
答案3
您可以使用更简单的语法。
\documentclass{article}
\usepackage{xparse}
\usepackage{pgffor}
\usepackage{amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\definematrix}{mm}
{% #1 = symbolic name, #2 = list of rows
\viesturs_matrix_define:nn { #1 } { #2 }
}
\NewDocumentCommand{\showmatrix}{m}
{
\seq_clear:N \l_tmpa_seq
\seq_map_inline:cn { l_viesturs_matrix_#1_seq }
{
\clist_set:Nn \l_tmpa_clist { ##1 }
\seq_put_right:Nx \l_tmpa_seq { \clist_use:Nn \l_tmpa_clist { & } }
}
\begin{bmatrix}
\seq_use:Nn \l_tmpa_seq { \\ }
\end{bmatrix}
}
\NewExpandableDocumentCommand{\matrixentry}{mmm}
{% #1 = matrix name, #2 = row index, #3 = column index
\viesturs_matrix_entry:nnn { #1 } { #2 } { #3 }
}
\NewExpandableDocumentCommand{\matrixrows}{m}
{
\seq_count:c { l_viesturs_matrix_#1_seq }
}
\NewExpandableDocumentCommand{\matrixcolumns}{m}
{
\int_use:c { l_viesturs_matrix_#1_int }
}
\cs_new_protected:Nn \viesturs_matrix_define:nn
{
\seq_new:c { l_viesturs_matrix_#1_seq }
\seq_set_split:cnn { l_viesturs_matrix_#1_seq } { ; } { #2 }
\int_zero:N \l_tmpa_int
\seq_map_inline:cn { l_viesturs_matrix_#1_seq }
{
\int_set:Nn \l_tmpa_int
{
\int_max:nn { \l_tmpa_int } { \clist_count:n { ##1 } }
}
}
\int_new:c { l_viesturs_matrix_#1_int }
\int_set:cn { l_viesturs_matrix_#1_int } { \l_tmpa_int }
}
\cs_new:Nn \viesturs_matrix_entry:nnn
{
\clist_item:fn { \seq_item:cn { l_viesturs_matrix_#1_seq } { #2 } } { #3 }
}
\cs_generate_variant:Nn \seq_set_split:Nnn { c }
\cs_generate_variant:Nn \clist_item:nn { f }
\ExplSyntaxOff
\definematrix{points}{-1,3;2,7;3,8}
\begin{document}
\matrixentry{points}{3}{2}
\foreach \x in {1,...,\matrixrows{points}}{% Over all rows
\foreach \y in {1,...,\matrixcolumns{points}}{% Over all columns
$\matrixentry{points}{\x}{\y}$,
}%
}
$\showmatrix{points}$
\end{document}