
후속 조치로 약간 다른 두 버전 간의 컴파일 시간 차이 나는 썼다쉼표로 구분된 문자열 목록에서 중복 항목 삭제.
문제 요약: 이전 질문에서는 텍스트의 참조에서 파생된 레이블인 문자열 목록을 사용하는 일부 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