Создание списка недублирующихся меток из текста «на лету»

Создание списка недублирующихся меток из текста «на лету»

В качестве продолжения Разница во времени компиляции между двумя немного разными версиями Я написалУдаление дубликатов из списка строк, разделенных запятыми.

Краткое описание проблемы: В первом вопросе был показан некоторый код TeX, который использовал список строк, которые были метками, полученными из ссылок в тексте. Однако этот список мог содержать дубликаты, и этот код не дедуплицировал этот список. Второй вопрос был сосредоточен на дедупликации этого списка после его сбора из текста.

Однако Дэвид Карлайл указал в чате, что, возможно, можно создать список без дубликатов в первом случае. Я предполагал, что будет быстрее и проще создать список с дубликатами, а затем удалить дубликаты, но, возможно, нет. В любом случае, мне было бы интересно решение, использующее этот подход.

Соответствующий обмен начался в

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

Связанный контент