즉석에서 텍스트를 사용하여 중복되지 않은 라벨 목록 작성

즉석에서 텍스트를 사용하여 중복되지 않은 라벨 목록 작성

후속 조치로 약간 다른 두 버전 간의 컴파일 시간 차이 나는 썼다쉼표로 구분된 문자열 목록에서 중복 항목 삭제.

문제 요약: 이전 질문에서는 텍스트의 참조에서 파생된 레이블인 문자열 목록을 사용하는 일부 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

관련 정보