是否可以存储由 foreach 生成的数组?

是否可以存储由 foreach 生成的数组?

例如,我想获取一个包含值的数组sin(1),sin(2),..,sin(100)并将其存储到变量中。有没有办法通过使用来获得此结果foreach

编辑:一个更复杂的例子:绘制 100 个随机点{(1,rnd),(2,rnd),...,(10,rnd)},然后绘制从这些点到它们的平均值的距离。

我不知道如何在 tikz 中实现它,这里是伪代码:

yarray = {}   //an array to store 100 random value
sum    = 0
for i = {1...100}
   yarray[i] = random
   sum = sum + yarray[i]
mean = sum/100
absarray = {}  //an array to store the distance from points to mean
for i = {1...100}
   absarray[i] = abs(yarray[i]-mean)

// draw the image
for i = {1...100}
   \fill (i,yarray[i]) circle (2pt)
   \fill (i,absarray[i]) circle (2pt)

答案1

这是一种方法。

\documentclass{article}
\usepackage{tikz}

\makeatletter
\newcommand\store[6][\x]{%
  % #1 = dummy variable
  % #2 = variable to store the list
  % #3 = expression
  % #4 = expression to store (with \pgfmathresult) and possibly #1
  % #5 = start point
  % #6 = end point
  \gdef\store@temp{\@gobble}%
  \foreach #1 in {#5,...,#6}{\pgfmathparse{#3}\xdef\store@temp{\store@temp,#4}}%
  \let#2=\store@temp
}
\makeatother

\begin{document}

\store{\sineslist}{sin(deg(\x))}{\pgfmathresult}{1}{100}

\show\sineslist

\store[\i]{\randlist}{rand}{(\i,\pgfmathresult)}{1}{20}

\show\randlist

\end{document}

报道内容如下:

> \sineslist=macro:
->0.84143,0.90924,0.14111,-0.75677,-0.95886,-0.27939,0.65697,0.9893,0.41208,-0.
544,-0.99995,-0.53654,0.42015,0.99057,0.65025,-0.28787,-0.96138,-0.75095,0.1498
6,0.91292,0.83662,-0.00885,-0.84619,-0.90555,-0.13234,0.76251,0.95636,0.27087,-
0.6636,-0.988,-0.40402,0.55139,0.99988,0.52907,-0.42815,-0.99173,-0.64352,0.296
34,0.96375,0.74509,-0.1586,-0.91647,-0.83174,0.01768,0.85086,0.90175,0.12357,-0
.7682,-0.9537,-0.26234,0.67021,0.98657,0.3959,-0.55878,-0.99971,-0.52153,0.4361
4,0.99284,0.6367,-0.30478,-0.9661,-0.73914,0.16733,0.92,0.8268,-0.02654,-0.8554
7,-0.8979,-0.11476,0.77385,0.95105,0.2538,-0.67673,-0.98512,-0.38777,0.56606,0.
99948,0.51398,-0.44408,-0.99385,-0.62988,0.3132,0.9683,0.73317,-0.17606,-0.9234
,-0.82178,0.03539,0.86002,0.89395,0.10597,-0.77942,-0.94824,-0.24522,0.68324,0.
98354,0.3796,-0.57335,-0.99916,-0.50635.

> \randlist=macro:
->(1,-0.86513),(2,-0.8214),(3,0.83136),(4,0.03825),(5,0.0602),(6,0.65846),(7,-0
.7918),(8,0.8938),(9,-0.13474),(10,-0.90755),(11,0.68077),(12,-0.1404),(13,-0.4
3602),(14,-0.08235),(15,0.65369),(16,-0.25284),(17,0.98817),(18,-0.09077),(19,0
.42735),(20,0.88712).

答案2

我不得不说,我没有理解你问题中的距离参数。我不会使用 PGF 或 TikZ,而是生成存储在文件中的数据数组。这样你就可以访问pgfplotstable并且它的宏非常快。TikZ 部分在 150 左右就卡住了,但后面的例子就跑得相当远了(当然还有一个原因是我的代码根本没有优化,所以这不仅仅是 TikZ 的错)。

这是一个包含 100 个样本点的示例,仅将其存储到数组中并稍后读取它们,也是我从手册 + 一些调整中编译的 PGFPLOTSTABLE 示例。

\documentclass{article}
\usepackage{pgfplotstable,booktabs}

%\pgfmathsetseed{226584}

\def\sample{100}
\pgfmathsetmacro{\runningrandarray}{rand} % Initial
\edef\runningmean{\runningrandarray}

\foreach \x[count=\xi from 1] in {2,...,\sample}{
\let\temprand\runningrandarray
\pgfmathsetmacro\tempres{rand}
\xdef\runningrandarray{\temprand,\tempres}
\pgfmathparse{(\xi*\runningmean+\tempres)/\x}
\xdef\runningmean{\pgfmathresult}
}
\xdef\randarray{{\runningrandarray}} % Double brace needed if you want to access via TikZ

\begin{document}
Some random points here : 

\begin{tikzpicture}
\foreach \x in {0,...,\number\numexpr\sample-1\relax}{
\pgfmathsetmacro\ycoord{\randarray[\x]}
    \node[circle,inner sep=1pt,fill=red,ultra thin] at (\x mm,\ycoord mm){};
    }
\end{tikzpicture}

and their current mean value is \runningmean

Instead we can directly go with PGFPLOTSTABLE package to produce the values: 

\pgfplotstablenew[
create on use/y/.style={create col/expr={\pgfplotstablerow+1}},
% define how the 'sine' column shall be filled:
create on use/sine/.style={create col/expr={sin(\pgfplotstablerow+1)}},
columns={y,sine}]{130}\loadedtable

\vspace{1cm}
\begin{minipage}[t]{0.58\textwidth}
show it as a table (columns skipped):
\centering
\pgfplotstabletypeset[
every head row/.style={before row=\toprule,after row=\midrule},
every last row/.style={after row=\bottomrule},
row predicate/.code={%
\ifnum#1>5\relax
\ifnum#1<125\relax
\pgfplotstableuserowfalse
\fi
\fi}
]
\loadedtable
\end{minipage}
\begin{minipage}[t]{0.4\textwidth}
or directly use it in plots

\begin{tikzpicture}
    \begin{axis}[width=4cm,height=7cm,xlabel={angle [deg]}]
    \addplot[no marks] table[x=y,y=sine]\loadedtable;
    \end{axis}
\end{tikzpicture}
\end{minipage}
\end{document}

在此处输入图片描述

答案3

不幸的是,我不知道如何处理与扩展相关的问题,因此无法为您提供简单的解决方案(尝试被注释掉了)。但是,我了解到使用包裹datatool对我来说效果很好:

在此处输入图片描述

笔记:

  • 我手动遍历数据库而不是使用,\DTLdisplaydb以便您可以看到如何遍历它(有趣的是您需要单独的条目)。
  • 这里的扩展专家可以向您展示如何扩展要存储的结果,但下面我尝试使用其中一种解决方案如何保存字符串的运行列表,然后逐个处理它们保存值列表sin

代码:

\documentclass{article}
\usepackage{tikz}
\usepackage{datatool}


%% https://tex.stackexchange.com/questions/14393/how-keep-a-running-list-of-strings-and-then-process-them-one-at-a-time
%\def\ListOfValues{}
%\makeatletter
%\newcommand{\AddToListOfValues}[1]{%
%    \g@addto@macro\ListOfValues{{#1}}%
%}
%\makeatother

\begin{document}
\DTLnewdb{TableOfSinValues}
\foreach \x in {1,...,10} {%
    \pgfmathparse{sin(deg(\x))}
    %\edef\temp\pgfmathresult
    %\AddToListOfValues{\temp}%
    \DTLnewrow{TableOfSinValues}
    \dtlexpandnewvalue
    \DTLnewdbentry{TableOfSinValues}{Degree}{\x}
    \DTLnewdbentry{TableOfSinValues}{SinValue}{\pgfmathresult}
}%

List of $\sin$ Values:\bigskip

%\DTLdisplaydb{TableOfSinValues}% for automated display
\begin{tabular}{cr}
$x$ [degrees] & $\sin{x}$ \\[0.5ex]
\DTLforeach{TableOfSinValues}{\Degree=Degree, \SinValue=SinValue}{%
    $\Degree$ & $\SinValue$\\
}%
\end{tabular}
\end{document}

相关内容