expl3 属性列表值作为 `clist` 与标记列表

expl3 属性列表值作为 `clist` 与标记列表

我有一个(可能)很长的属性列表,values目前,它们只是标记列表。现在,我想实现一些键可能有多个值。我将把这些多个值存储在中clists

因此,对于每个键,我必须测试其值是clist还是只是一个标记列表。键可能只有一个值的情况可以看作 的一个特殊情况clist,其中只能在列表中插入一个值。

我请求建议,哪种方法更容易编程:

  1. values可以是标记列表或clists? 或
  2. values所有都是clists,但其中一些只能有一个元素?

( key, value) 对通常只设置一次,而 将value被检索几次(其中一些会检索几次,但我估计不会超过五次)。我预计这两种方法的运行时间不会有很大差异。我不确定内存效率是否会成为“全部方法”的问题clist

编辑

egreg'sanswwr 很棒(像往常一样)。但我没有完整解释这个问题。第一次设置(keyvalue)对时,我没有列表的所有元素(如果它是列表)。所以,我必须:

  1. 检索value
  2. 检查它是否是一个列表,
  3. 在列表中插入新值

多次,直到列表类型keys填满。如果我将所有值定义为clists。我可以跳过步骤 2。但是,当检索它们时,我想我必须检查是否是key列表。

问题归结为跳过第 2 步是否会使编程变得更容易。

(经过更深入的思考,它可能同样简单/复杂,因为它只是将更难的部分转移到设置或检索values

答案1

\prop_put:Nnn它对你存储的数据不做任何解释,也就是说它不理解这些数据;它就像\tl_set:Nn在这方面它很像,所以在某种意义上,属性列表(清单)是标记列表的集合(tl) 按名称进行索引。

这可以是列表? 是的,为什么不?

您可以照常存储价值

\prop_put:Nnn \l_textnik_test_prop { a } { 1,2,3,4 }

然后通过将其分配给tl多变的:

\cs_new_protected:Nn \textnik_prop_get_clist:NnN
 {
  \prop_get:NnN #1 {#2} \l__textnik_prop_get_clist_tl
  \clist_set:NV #3 \l__textnik_prop_get_clist_tl
 }

以便

\textnik_prop_get_clist:NnN \l_textnik_test_prop { a } \l_textnik_test_clist

效果与

\clist_set:Nn \l_textnik_test_clist { 1,2,3,4 }

如果你想提取值作为tl, 使用\clist_get:NnN


这是一个不同的实现:每个属性引用一个clist

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn
% Define a new data type pcl, only local settings.
% Add variants as needed and support for global setting.
\cs_new_eq:NN \textnik_pcl_new:N \prop_new:N
\cs_new_eq:NN \textnik_pcl_clear_new:N \prop_clear_new:N
\cs_new_eq:NN \textnik_pcl_clear:N \prop_clear:N
\cs_new_eq:NN \textnik_pcl_set_eq:NN \prop_set_eq:NN
\cs_new_eq:NN \textnik_pcl_remove:NN \prop_remove:NN

% a global counter
\int_new:N \g__textnik_pcl_serial_int

\cs_new_protected:Nn \__textnik_pcl_check:Nn
 {
  \prop_if_in:NnF #1 { #2 }
   {% the property doesn't already exist
    \int_gincr:N \g__textnik_pcl_serial_int
    \prop_put:Nnx #1 { #2 } { \int_to_arabic:n { \g__textnik_pcl_serial_int } }
    \clist_new:c { l__textnik_pcl_ \int_to_arabic:n { \g__textnik_pcl_serial_int } _clist }
   }
 }

% adding items to a pcl
\cs_new_protected:Nn \textnik_pcl_put:Nnn
 {
  \__textnik_pcl_check:Nn #1 { #2 }
  \clist_set:cn { l__textnik_pcl_ \prop_item:Nn #1 { #2 } _clist } { #3 }
 }
\cs_new_protected:Nn \textnik_pcl_put_left:Nnn
 {
  \__textnik_pcl_check:Nn #1 { #2 }
  \clist_put_left:cn { l__textnik_pcl_ \prop_item:Nn #1 { #2 } _clist } { #3 }
 }
\cs_new_protected:Nn \textnik_pcl_put_right:Nnn
 {
  \__textnik_pcl_check:Nn #1 { #2 }
  \clist_put_right:cn { l__textnik_pcl_ \prop_item:Nn #1 { #2 } _clist } { #3 }
 }

% retrieving items from a pcl
\cs_new_protected:Nn \textnik_pcl_get:NnN
 {
  \clist_set_eq:Nc #3 { l__textnik_pcl_ \prop_item:Nn #1 { #2 } _clist }
 }

% showing a pcl
\cs_new_protected:Nn \textnik_pcl_show:N
 {
  \prop_map_function:NN #1 \__textnik_pcl_show:nn
 }
\cs_new_protected:Nn \__textnik_pcl_show:nn
 {
  \clist_show:c { l__textnik_pcl_ #2 _clist }
 }

%%%% Test

\textnik_pcl_new:N \l_textnik_test_pcl
\textnik_pcl_put:Nnn \l_textnik_test_pcl { A } { A1,A2,A3 }
\textnik_pcl_put_right:Nnn \l_textnik_test_pcl { A } { A4,A5 }
\textnik_pcl_put_left:Nnn \l_textnik_test_pcl { A } { A0 }
\textnik_pcl_put:Nnn \l_textnik_test_pcl { B } { B1,B2,B3 }
\textnik_pcl_put_right:Nnn \l_textnik_test_pcl { B } { B4,B5 }
\textnik_pcl_put_left:Nnn \l_textnik_test_pcl { B } { B0 }

\clist_new:N \l_textnik_test_clist
\textnik_pcl_get:NnN \l_textnik_test_pcl {A} \l_textnik_test_clist
\clist_show:N \l_textnik_test_clist
\textnik_pcl_get:NnN \l_textnik_test_pcl {B} \l_textnik_test_clist
\clist_show:N \l_textnik_test_clist

%\textnik_pcl_show:N \l_textnik_test_pcl

Apcl实际上是 a prop,但存储的属性只是引用clists 数组的数字。

输出为

The comma list \l_textnik_test_clist contains the items (without outer
braces):
>  {A0}
>  {A1}
>  {A2}
>  {A3}
>  {A4}
>  {A5}.
<recently read> }
                 
l.71 \clist_show:N \l_textnik_test_clist
                                        
? 
The comma list \l_textnik_test_clist contains the items (without outer
braces):
>  {B0}
>  {B1}
>  {B2}
>  {B3}
>  {B4}
>  {B5}.
<recently read> }
                 
l.73 \clist_show:N \l_textnik_test_clist

相关内容