2016-07-13 3 views
0

에 추가되지 않은 이유는 다음과 같이 나는 작은 텍스트 파일이 있습니다목록 라켓

one, 50, 40, 65, 500 
two, 80, 70, 100, 250 
three, 100, 55, 125, 100 
four, 50, 45, 58, 850 

내가 그것을 읽고 각 라인의 2 열에있는 모든 값의 목록을 만들려고 노력하고 있습니다.

#lang racket 
(define (testfn fname) 
(let ((sl '()) (list2 (list)) (templist '()) (ss "")) 
    (set! sl (file->lines fname)) 
    (for ((line sl)) 
     (set! templist (string-split line ",")) 
     (println templist) 
     (set! ss (list-ref templist 1)) 
     (println ss) 
     (append list2 ss)  ; does not work 
     (append list2 (list ss)) ; does not work 
     (cons ss list2)   ; does not work 
     (cons (list ss) list2) ; does not work 
     (cons list2 (list ss)) ; does not work 
     (cons list2 ss)   ; does not work 
     (println list2) 
) 
    (println list2))) 

(testfn "test.txt") 

그러나, '리스트 2는'내가 위에서 사용하고있는 많은 방법 중 하나를 가진 문자열 'SS'가 추가 점점되지 않은 : 다음 내가 사용하고있는 코드입니다. 출력 결과는 다음과 같습니다.

'("one" " 50" " 40" " 65" " 500") 
" 50" 
'() 
'("two" " 80" " 70" " 100" " 250") 
" 80" 
'() 
'("three" " 100" " 55" " 125" " 100") 
" 100" 
'() 
'("four" " 50" " 45" " 58" " 850") 
" 50" 
'() 
'() 
> 

어디에서 문제가 발생하며 어떻게 해결할 수 있습니까?

편집 : 실수를 수정하는 @JohnClements 지적한 후, 다음 코드는 작동 :

#lang racket 
(define (testfn fname) 
(let ((sl '()) (list2 (list)) (templist '()) (ss "")) 
    (set! sl (file->lines fname)) 
    (for ((line sl)) 
     (set! templist (string-split line ",")) 
     (set! ss (list-ref templist 1)) 
     (set! list2 (append list2 (list ss))) 
     (println list2) 
) 
    (println list2))) 

(testfn "test.txt") 

출력 :

'(" 50") 
'(" 50" " 80") 
'(" 50" " 80" " 100") 
'(" 50" " 80" " 100" " 50") 
'(" 50" " 80" " 100" " 50") 
> 

답변

3

아싸! 코드는 매우 긴급한 스타일로 작성되었습니다. 이 스타일의 코드는 읽고 유지하기가 어렵습니다. 코드를 훨씬 작은 함수로 분해하고 How To Design 프로그램 설계법 (www.htdp.org)에 따라 코드를 개발하면 훨씬 더 깨끗한 것으로 마무리 될 것입니다.

"append"와 같은 함수가 돌연변이를 일으키는 것으로 가정하고 있습니다. 특히 전화를 걸면 (예 : (append a b)) 전화를 건 다음 목록 중 하나 또는 둘 다 다를 것이라고 가정합니다. 그렇지 않다. 이 코드를 실행 한 후,

#lang racket 

(define a 3) 
(define b 6) 
(+ a b) 
(- b a) 
(+ (* 2 a) b) 

ab의 값이 무엇 일 것입니다 : 나는이 코드를 작성 상상 이유

확인하려면?

아마 3과 6이 될 것이라고 생각합니다. 그 이유는 추가 과 뺄셈이 인수를 변경하지 않기 때문입니다. 동일한 것은 consappend입니다. 따라서 (append a b)을 호출하면 새로운 목록이 생성되지만,이 값을 사용하지 않으면 아무데도 가지 않습니다.

다음

, ... 나를 매우 신속하게, 당신을 위해 몇 가지 코드를 작성할 수

편집 :

#lang racket 

(require rackunit) 

;; given a list of lists, return the second of each list: 
;; list-of-lists -> list 
(define (second-element-map lol) 
    (cond [(empty? lol) empty] 
     [else (cons (second (first lol)) 
        (second-element-map (rest lol)))])) 

;; let's test it: 
(check-equal? (second-element-map '((a b c) (d e f g) (1 2 3))) 
       '(b e 2)) 

;; given a list of lines, split each one into commas 
(define (split-each-line lines) 
    (cond [(empty? lines) empty] 
     [else (cons (string-split (first lines) ",") 
        (split-each-line (rest lines)))])) 

;; let's test it: 
(check-equal? (split-each-line '("a,34,2987" "hn th, th")) 
       '(("a" "34" "2987") 
       ("hn th" " th"))) 

;; given a filename, return a list containing the second element of 
;; each list 
;; path-string -> list 
(define (testfn fname) 
    (second-element-map (split-each-line (file->lines fname)))) 

(testfn "/tmp/abc.txt") 
: 여기

는 HTDP 스타일을 사용하여 각 목록의 두 번째 요소를 반환하는 프로그램입니다

더 짧을 수 있습니까? 당연하지. HtDP 스타일은 깨끗하고 작동하도록 보장됩니다.

...하지만 여기에 내가 개인적 소비를 위해이 프로그램을 써서 방법은 다음과 같습니다

#lang racket 
(define (testfn2 fname) 
    (for/list ([l (in-list (file->lines fname))]) 
    (second (string-split l ",")))) 

(testfn2 "/tmp/abc.txt") 
+0

예, 나는 그것을 얻었다. (set! list2 (append list2 (list ss)))가 작동했습니다. 감사. – rnso

+1

두 번째 (더 짧은) 프로그램이 어떻게 작동하는지 설명 할 수 있다면 좋을 것입니다. – rnso

+0

예! 이 프로그램은 다음과 같이 말합니다. testfn2는 'fname'이라는 인수가있는 함수입니다.전화를 걸면 파일의 모든 줄을 고려하고 그 줄을 쉼표로 분리 한 결과의 두 번째 결과를 가져 와서 얻은 결과 목록을 만듭니다. –