动态地从文本中构建非重复标签列表

动态地从文本中构建非重复标签列表

作为 两个略有不同的版本之间的编译时间差异 我写从逗号分隔的字符串列表中删除重复项

问题摘要:前一个问题展示了一些 TeX 代码,这些代码使用了一个字符串列表,这些字符串是从文本中的引用派生出来的标签。但是,该列表可能包含重复项,并且该代码没有对该列表进行重复项删除。后一个问题重点是从文本中收集该列表后对其进行重复项删除。

然而,David Carlisle 在聊天中表示,首先可以创建一个没有重复项的列表。我曾以为创建一个有重复项的列表,然后删除重复项会更快、更容易,但也许不是。无论如何,我对使用此方法的解决方案很感兴趣。

相关交易所开始于

http://chat.stackexchange.com/transcript/message/20082058#20082058

大卫写道

我不明白为什么需要 \clist_remove_duplicates:N 如果重复是一个问题那么就不要将它们放入列表中。

我回答

@DavidCarlisle 嗯,每次添加时你都必须检查列表。当然可以这样做,但最后删除重复项可能更有效率。

David 对此的回应是:

@FaheemMitha 我对此表示怀疑

并跟进

@FaheemMitha 您正在添加引用,因此如果 \csname r@#1\endcsname 已定义,则您之前已经看到过此引用,无需再次添加。需要建立一个包含重复项的列表

我回答:

您大概是说可以修改原始问题中的代码,这样就不会添加重复代码。

他回应道

@FaheemMitha 是的,虽然没有测试 r@#1(因为它只是告诉你有一个标签)但你可以让每个引用留下一个 csname,这样你就知道你已经看到了它(这用空间换取时间)

答案1

您可以定义一个标志宏(任何内容),然后如果该宏已经定义,则不需要添加新条目。

% VERSION 1
\iftrue
\makeatletter
\let\oldref\ref
\def\ref#1{%
  \expandafter\ifx\csname R@#1\endcsname\relax
  \global\expandafter\let\csname R@#1\endcsname\@empty
  \immediate\write\@auxout{%
    \string\gappto\string\ReferencedIDs{#1,}%
  }%
 \fi
  \oldref{#1}%
}
\def\ReferencedIDs{}
\makeatother

\else
% VERSION 2

 \makeatletter
 \AtBeginDocument{\providecommand\ReferencedIDs{}}
 \AtEndDocument{\immediate\write\@auxout{\gdef\string\ReferencedIDs{\ReferencedIDs}}}
 \let\oldref\ref
 \def\ref#1{%
  \expandafter\ifx\csname R@#1\endcsname\relax
  \global\expandafter\let\csname R@#1\endcsname\@empty
   \g@addto@macro\ReferencedIDs{#1,}%
  \fi
   \oldref{#1}%
 }
 \makeatother
\fi

相关内容