Tcl 리스트에서 여러 값을 제외하려면 원본을 foreach로 순회하고, 제외 목록에 없는 항목만 새 리스트에 lappend한다. lsearch -not에 제외 목록을 여러 pattern 인자로 넘기는 방식은 동작하지 않는다.
제외할 값 목록으로 필터링하기
set clocks {clk1 clk2 clk3 clk2}
set excluded {clk2 clk3}
set remaining {}
foreach clock $clocks {
if {[lsearch -exact $excluded $clock] < 0} {
lappend remaining $clock
}
}
puts $remaining
출력은 clk1이다. 원본 순서를 유지하고, 제외되지 않은 값의 중복도 보존한다. -exact는 glob pattern이 아니라 문자열 전체가 같은지 비교한다.
원문의 lsearch 확장 방식이 맞지 않는 이유
Tcl의 {*}는 list를 여러 command argument로 확장한다. 하지만 lsearch는 검색 대상 list와 하나의 pattern을 받는 명령이다. 제외 list를 여러 pattern 인자로 확장하면 여러 값을 한 번에 제외하는 필터가 되지 않는다. 또한 -not은 하나의 검색 pattern과 일치하지 않는 항목을 고르는 옵션이지, 여러 pattern 목록을 받는 옵션이 아니다.
따라서 여러 제외 값을 처리할 때는 위처럼 foreach에서 각 값을 검사하는 편이 의도를 명확히 보여준다. 목록이 크고 반복 성능이 중요하다면 dictionary 기반 membership 검사도 고려할 수 있지만, 일반적인 작은 clock list에는 이 코드가 충분하다.
확인할 점
- Tcl 리스트에 공백이 포함된 요소가 있어도 list 명령으로 구성했다면 안전하게 순회한다.
- 대소문자와 문자열이 정확히 일치해야 하므로
-exact를 유지한다. - 결과가 빈 리스트일 수 있는 경우를 호출하는 쪽에서 처리한다.
공식 자료
원문 기록
한 줄 요약
제외 목록을 lsearch -exact로 검사하면서 원본을 순회하면 여러 list 요소를 예측 가능하게 제거할 수 있다.