2011-01-06 7 views
6

이 질문은 아마도 얼굴 표정으로 끝날 것이지만 나는 잠시 동안 시험을 보았고 hyperspec을 읽었음에도 불구하고 여전히 붙어 있습니다.형식 - 표 인쇄에 대한 도움말

기본적으로 내가하고 싶은

(format t "~{|~{ ~5d~}|~%~}" '((1 23 2 312) (23 456 1 7890))) 

같은 대신의 하드 코딩이 목록에서 계산해야 5 (중첩 된 목록 + 1에서 가장 긴 요소의 길이) 줄 뭔가 같은

| 1 23  2 312| 
| 23 456  1 7890|  

어쩌면 내가 여기 너무 복잡하게 생각하고 내가 원하는 것을 할 수있는 쉬운 방법이 있습니다,하지만 난 내가 나갈 수없는 정신 구석으로 자신을 달렸다 생각합니다. format 마법은 형식 문자열 자체를 가서 다른 반복 구조를 사용하거나 생성 할 수 있습니다 : longest-member의 정의는 독자에게 연습 문제로 남겨

(defun facepalm-printer (lol) 
    (format t (format nil "~~{|~~{ ~~~ad~~}|~~%~~}" 
        (longest-member lol)) 
      lol)) 

+0

당신이 원하는대로 할 수있는'~'컨트롤이 있을지 모르지만, 나는 2 단계로 이것을 할 것입니다. 가장 넓은 요소를 계산 한 다음 그것을 사용하여 포맷 문자열 (형식으로!)을 만든 다음 호출합니다 형식으로 테이블을 작성하십시오. 그래서 이것은 1 라인 함수 대신 3 라인 함수입니다. :-) – Ken

답변

3

width에 바인딩되어, 당신은이 작업을 수행 할 수 있습니다

(format t "~{|~{ ~Vd~}|~%~}" width '((1 23 2 312) (23 456 1 7890))) 

5V로 대체되었습니다 및 widthFORMAT/

에 인수로 추가되었습니다 편집 : 원래 응답이 중첩 된 지시문을 올바르게 계산하지 못했습니다.

형식 제어 문자열 V은 상수 값 대신 사용할 수 있습니다. 이는 해당 값이 인수 목록에서 가져와야 함을 나타냅니다.

이 작업을 시도 할 수 있습니다 :

(setf width 5) 
(setf data '((1 23 2 312) (23 456 1 7890))) 

(format t "~{|~{ ~{~Vd~}~}|~%~}" 
    (mapcar #'(lambda (r) (mapcar #'(lambda (v) (list width v)) r)) data)) 

이 형식 문자열은 각 값을 선행 원하는 폭을 필요로한다. (mapcar ...) 표현이이를 수행합니다.

+1

+1 좋은 답변입니다. 최대 너비는 적어도 계산하기 쉽습니다 (적어도 모든 숫자가 양수인 경우). 예를 들어,'(1+ (apply # 'max mapcar #'(lambda (x) (floor (log x 10))) '(1 10 100 1000 200000))))'. –

+0

나는 폭넓게 인수 목록에 스 플라이 싱하는 것이 불필요하게 복잡하고 낭비적인 것처럼 보였으므로이 솔루션을 간결하게 거부했다. – Svante

+0

+1 그리고'V '가 내가 찾고있는 것 (그리고 반복해서 놓친 것 같습니다) 이후로 받아 들여졌습니다. 나는 Svanet의 포인트를 보았다. +1도 거기에있다. :) –

5

나는 당신이 두 가지 옵션이 있다고 생각합니다. 필요한 폭을 가정