テキストから重複しないラベルのリストを即座に構築する

テキストから重複しないラベルのリストを即座に構築する

続きとして わずかに異なる2つのバージョン間のコンパイル時間の違い 私が書いたカンマ区切りの文字列リストから重複を削除する

問題の概要: 前の質問では、テキスト内の参照から派生したラベルである文字列のリストを使用する TeX コードが示されていました。ただし、そのリストには重複が含まれている可能性があり、そのコードはそのリストの重複を排除していませんでした。後者の質問では、テキストからリストを収集した後、そのリストの重複を排除することに重点が置かれていました。

しかし、David Carlisle はチャットで、最初に重複のないリストを作成できるかもしれないと示唆しました。重複のあるリストを作成してから重複を削除する方が速くて簡単だろうと思っていましたが、そうではないかもしれません。いずれにせよ、このアプローチを使用するソリューションに興味があります。

関連する交換は

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

デイヴィッドが書いた

重複が問題になる場合は、重複をリストに入れなければよいのですが、なぜ \clist_remove_duplicates:N が必要なのかわかりません。

私はこう答えた

@DavidCarlisle そうですね、追加するたびにリストをチェックする必要があります。確かにそうすることもできますが、最後に重複を削除する方が効率的でしょう。

デイビッドはこう答えました。

@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

関連情報