Crear una lista de etiquetas no duplicadas a partir de texto sobre la marcha

Crear una lista de etiquetas no duplicadas a partir de texto sobre la marcha

Como seguimiento a Diferencia en el tiempo de compilación entre dos versiones ligeramente diferentes escribíEliminar duplicados de una lista de cadenas separadas por comas.

Resumen del problema: la pregunta anterior mostraba un código TeX que usaba una lista de cadenas que eran etiquetas derivadas de referencias en el texto. Sin embargo, esa lista podría contener duplicados y ese código no eliminó esa lista. La última pregunta se centró en deduplicar esa lista después de recopilarla del texto.

Sin embargo, David Carlisle indicó en el chat que podría ser posible crear una lista sin duplicados en primera instancia. Supuse que sería más rápido y fácil crear una lista con duplicados y luego eliminarlos, pero tal vez no. En cualquier caso, me interesaría una solución que utilice este enfoque.

El intercambio correspondiente comenzó en

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

donde David escribió

No veo por qué necesitarías \clist_remove_duplicates:N si los duplicados son un problema, entonces simplemente no los pongas en la lista.

respondí con

@DavidCarlisle bueno, tendrías que consultar la lista en cada adición. Se podría hacer eso, ciertamente, pero probablemente sea más eficiente eliminar los incautos al final.

A lo que David respondió:

@FaheemMitha lo dudo

y siguió con

@FaheemMitha Estás agregando una referencia, por lo que si \csname r@#1\endcsname ya está definida, has visto esta referencia antes y no necesitas agregarla nuevamente. Es necesario crear una lista con duplicados.

Respondí:

Probablemente esté diciendo que el código de la pregunta original se puede modificar para que no se agreguen duplicados.

a lo que respondió

@FaheemMitha sí, aunque no estoy probando r@#1 (ya que eso solo te dice que hay una etiqueta), pero puedes hacer que cada árbitro deje un csname para que sepas que lo has visto (esto intercambia espacio por tiempo)

Respuesta1

Puede simplemente definir una macro de marca (para cualquier cosa) y luego no agregar una nueva entrada si la macro ya está definida.

% 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

información relacionada