如何同时对链接数据进行排序?

如何同时对链接数据进行排序?

抱歉,标题不清楚;我不确定如何描述我想做的事情(请随意编辑我的标签)。但这是我最好的想法:

我有一组数据;每个数据都是一对有序的文本。假设对于每个数据,我都可以创建一个相应的宏,该宏“知道”其两个文本部分。我不知道这样的宏如何工作,但假设该宏\mynumber表示(sixtwo)和\mycolor表示(bluered)。

我想要的是一个宏,\arrange这样编译

Lorem ipsum \mynumber, dolor sit amet \mycolor, etc...

\arrange

生产

Lorem ipsum six, dolor sit amet blue, etc...

two, red

我正在寻找的关键属性是\arrange显示第二个条目按照上文中提到的数据的顺序。也就是说,如果我编辑文档的第一部分,使得\mycolor出现在之前\mynumber,那么我希望twored在下面交换位置。

我希望避免必须单独指定我在文本第一部分中提及数据的顺序,然后将其传递给\arrange;关键是我希望能够无忧无虑地编辑文档的第一部分,并让数据的第二个条目以正确的顺序显示在下面,而不必费力地重新排序任何事物文档的其他地方用手写方式。

输出格式的灵活性越高越好\arrange——例如,如果我改变主意并想\arrange将其结果放在单独的行上而不是用逗号分隔,我希望这是可能的。

答案1

您需要以有意义的方式重新排列数据。您描述的是元组,它们只是键值对,例如

two=red
six=blue

处理它们的一个简单方法是使用宏输入这些信息:

\newcommand\two{red}
\newcomand\six{blue}

但是,这可能有点难以输入,而且可能有一种方法可以实现自动化,所以让我们假设宏one, two, three etc是颜色,然后我们可以将它们保存在逗号分隔的列表中:

\colorlist{one,two,three,four,five,six}

和颜色作为\colorlistvalues{green,blue,yellow,orange,purple,red}

然后,我们可以自动迭代这两个列表以自动创建宏\one,\two等,或者创建一个实用程序来添加键值对。后者更灵活且语义正确:

 \addacolor{one}{red}
 \addacolor{two}{blue}
 \addacolor{three}{purple}

以下是完整的极简版:

\documentclass{article}
\makeatletter

\def\colorlist{}
\def\colorlistvalues{}

\def\addacolor#1#2{%
\g@addto@macro\colorlist{#1,}
\g@addto@macro\colorlistvalues{#2,}
\expandafter\def\csname#1\endcsname{#2}
}
\makeatother
\begin{document}

\addacolor{one}{red}
\addacolor{two}{blue}
\addacolor{three}{purple}


\one,\two

\colorlist

\colorlistvalues
\end{document}

另请参阅如何设置属性https://tex.stackexchange.com/a/37096/963,这与你想要的非常相似,以及向书籍类添加传记列表

答案2

\arrangement下面的代码通过在调用\mynumberand/or时构建一个列表 ( ) 来实现你想要的功能\mycolor。因此,无论你以何种顺序调用它们,列表都是在命令。

在此处输入图片描述

\documentclass{article}
\makeatletter
\def\storenumber(#1,#2){%
  \def\mynumber@one{#1}% Store first argument
  \def\mynumber@two{#2}% Store second argument
}
\def\storecolor(#1,#2){%
  \def\mycolor@one{#1}% Store first argument
  \def\mycolor@two{#2}% Store second argument
}
\let\arrangement\relax% Empty arrangement
\def\mynumber{%
  \mynumber@one% Set first number
  \setbox0=\hbox{\arrangement}%
  \ifdim\wd0=0pt % Check if \arrangement already has an item
    \edef\arrangement{\mynumber@two}%
  \else % \arrangement DOES have an item
    \edef\arrangement{\arrangement, \mynumber@two}%
  \fi%
}
\def\mycolor{%
  \mycolor@one% Set first colour
  \setbox0=\hbox{\arrangement}%
  \ifdim\wd0=0pt % Check if \arrangement already has an item
    \edef\arrangement{\mycolor@two}%
  \else % \arrangement DOES have an item
    \edef\arrangement{\arrangement, \mycolor@two}%
  \fi%
}
\def\arrange{%
  \arrangement% Set \arrangement
  \let\arrangement\relax% Clear/erase arrangement
}
\makeatother
\begin{document}

% Setup number/colour
\storenumber(six,two) \storecolor(blue,red)

Lorem ipsum \mynumber, dolor sit amet \mycolor, etc\ldots

\arrange % Print \arrangement

Lorem ipsum \mycolor, dolor sit amet \mynumber, etc\ldots

\arrange % Print \arrangement

\end{document}

\storenumber(<one>,<two>)\storecolor(<one>,<two>)设置了两对数据点。\mynumber每个\mycolor设置它们的第一个对,同时还检查它应该如何添加到一个调用的宏中\arrangement(它可能是第一个或后面的项目)。\arrange设置第二个项目对的构造/有序排列。

答案3

\documentclass[a4paper]{article}

\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\newpair}{ m m m }
  {
   \cs_new_protected:Npn #1 { \zevc_print_and_add:nn { #2 } { #3 } }
  }
\cs_new:Npn \zevc_print_and_add:nn #1 #2
  {
   #1 % print the first element
   \cs_if_exist:cF { zevc_ \tl_to_str:n { #1 + #2 } _tl } % store the second element
     {
      \seq_gput_right:Nn \g_zevc_keys_seq { #2 }
      \tl_new:c { zevc_ \tl_to_str:n { #1 + #2 } _tl } % only once
     }
  }
\seq_new:N \g_zevc_keys_seq
\NewDocumentCommand{\arrange}{ }
  {
   \seq_gpop_right:NN \g_zevc_keys_seq \l_tmpa_tl % detach the last element
   \seq_map_inline:Nn \g_zevc_keys_seq { ##1,~ } \tl_use:N \l_tmpa_tl
   \seq_gput_right:NV \g_zevc_keys_seq \l_tmpa_tl % restore for possible future use
  }
\ExplSyntaxOff

\newpair{\mycolor}{blue}{red}
\newpair{\mynumber}{six}{two}

\begin{document}

Lorem ipsum \mynumber, dolor sit amet \mycolor, etc...

\arrange

\end{document}

\newpair命令定义宏:它将名称、第一个值和第二个值作为参数:

\newpair{\mynumber}{six}{two}

当您使用 时\mynumber,则会打印“six”,并将“two”添加到序列 中\g_zevc_keys_seq,但前提是它之前没有被添加过。为了检查这一点,我们设置了一个新的标记列表变量,其名称由 和 组成,zev_c以确保唯一性(我们假设有序对都是不同的)。当然,如果您希望稍后打印所有第二个元素(而不考虑重复项),则这不是必需的。six+two_tl

\arrange命令只是按顺序打印迄今为止逐步添加的所有项目。为了打印它们并用逗号分隔,我们分离最后一个元素,打印所有剩余元素,后跟一个逗号和一个空格,然后打印最后一个元素。然后我们恢复序列,以备将来使用。顺序将是文本中出现的顺序。

相关内容