首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么没有在球拍中附加列表?

为什么没有在球拍中附加列表?
EN

Stack Overflow用户
提问于 2016-07-13 23:07:05
回答 1查看 670关注 0票数 0

我有一个小文本文件,如下所示:

代码语言:javascript
复制
one, 50, 40, 65, 500
two, 80, 70, 100, 250
three, 100, 55, 125, 100
four, 50, 45, 58, 850

我试图阅读它,并列出每一行第二列中的所有值。下面是我使用的代码:

代码语言:javascript
复制
#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")

但是,“list2”并没有在字符串'ss‘的后面加上我上面使用的许多方法中的任何一个。输出显示:

代码语言:javascript
复制
'("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指出的错误后,以下代码工作:

代码语言:javascript
复制
#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")

输出:

代码语言:javascript
复制
'(" 50")
'(" 50" " 80")
'(" 50" " 80" " 100")
'(" 50" " 80" " 100" " 50")
'(" 50" " 80" " 100" " 50")
> 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-13 23:39:58

呀!您的代码是以非常命令式的方式编写的。这种样式的代码很难阅读和维护。我想您会发现,如果您将代码分解成小得多的函数,并根据“如何设计程序设计配方”(www.htdp.org)开发代码,您最终会得到更干净的东西。

您遇到的基本问题之一是假设诸如“追加”之类的函数会导致突变。具体来说,假设如果调用,例如,(append a b),那么其中的一个或两个列表在调用后会有所不同。事实并非如此。

为了了解原因,想象一下我编写了以下代码:

代码语言:javascript
复制
#lang racket

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

在运行这段代码之后,ab的值是什么?

我想你可能会认为它们仍然是3和6,这是因为加法和减法不会改变它们的论点。consappend也是如此。因此,调用(append a b)会产生一个新的列表,但是如果您不使用该值,那么它就不会出现在任何地方。

给你,让我给你写些代码,很快.

编辑:

下面是一个程序,它使用HtDP样式返回每个列表的第二个元素:

代码语言:javascript
复制
#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样式是干净的,并且保证工作正常。

..。但以下是我为个人消费而编写的程序:

代码语言:javascript
复制
#lang racket
(define (testfn2 fname)
  (for/list ([l (in-list (file->lines fname))])
    (second (string-split l ","))))

(testfn2 "/tmp/abc.txt")
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38363123

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档