如果我有一个包含3个不同对象的列表,这些对象用全大写字符串相互分隔,我该如何将它们捆绑到3个列表的列表中?
我只是到目前为止
#lang racket
(define (test-string4 lst keyword)
(let ((kw (string-upcase keyword)))
(cond ((null? lst) '())
((string-upper-case? (car lst))
(list
列出'(" POLYLINE"" 2"" 3" ..." LINE"&#34 ; 2"" 3" ...) 它应该分解为(" POLYLINE"" 2"" 3" ...)(" LINE"& #34; 2"" 3" ...))
答案 0 :(得分:2)
假设string-upper-case?
已经定义(例如,使用andmap
):
(define (string-upper-case? str)
(andmap char-upper-case?
(string->list str)))
...我们可以使用SRFI-1中的break
编写一个通用的,更简单的,可以说是更惯用的实现,将列表拆分为具有以给定条件开头的元素的子列表,在本例中为全大写字符串:
(require srfi/1)
(define (splitter pred? lst)
(if (empty? lst)
empty
(let-values ([(data tail) (break pred? (rest lst))])
(cons (cons (first lst) data)
(splitter pred? tail)))))
每个元素序列的长度并不重要,只要我们尊重关键字是全大写字符串的约定,我们甚至不必传递关键字列表。例如:
(splitter string-upper-case?
'("POLYLINE" "2" "3" "4" "LINE" "2" "3" "TEST" "1"))
=> '(("POLYLINE" "2" "3" "4") ("LINE" "2" "3") ("TEST" "1"))
答案 1 :(得分:1)
这似乎可以做你想要的,虽然string-upper-case?
似乎没有在球拍中定义。
(define (splitter lst curr)
(cond ((null? lst) ; Put current "object" in a list
(cons curr '()))
((string-upper-case? (car lst)) ; Starting a new "object"
(let ((rslt (splitter (cdr lst) (list (car lst)))))
(if (null? curr)
rslt ; This is the only object
(cons curr rslt)))) ; Add last-finished object to front of result
(else ; Continue w/ current "object"
(splitter (cdr lst) (append curr (list (car lst)))))))
(define (test-string4 lst)
(splitter lst '()))
答案 2 :(得分:1)
我想知道您的数据结构是否真的适合您的需求,但我们继续:
首先我们定义take-right-until
,它会根据谓词f
拆分最右边的子列表:
(define (take-right-until lst f)
(let loop ((spl1 (reverse lst)) (spl2 null) (found #f))
(if (or found (null? spl1))
(values (reverse spl1) spl2)
(let ((c (car spl1)))
(loop (cdr spl1) (cons c spl2) (f c))))))
测试:
> (take-right-until '("POLYLINE" "2" "3" "LINE" "4" "5" ) (curryr member '("POLYLINE" "LINE")))
'("POLYLINE" "2" "3")
'("LINE" "4" "5")
> (take-right-until '("POLYLINE" "2" "3") (curryr member '("POLYLINE" "LINE")))
'()
'("POLYLINE" "2" "3")
然后test-string4
:
(define (test-string4 lst kwds)
(define kw (map string-upcase kwds))
(define f (curryr member kw))
(let loop ((lst lst) (res null))
(if (null? lst)
res
(let-values (((spl1 spl2) (take-right-until lst f)))
(loop spl1 (cons spl2 res))))))
测试:
> (test-string4 '("POLYLINE" "2" "3" "LINE" "4" "5" ) '("polyline" "line"))
'(("POLYLINE" "2" "3") ("LINE" "4" "5"))
> (test-string4 '("POLYLINE" "2" "3" "LINE" "4" "5" "SQUARE" "6" "7" "8") '("polyline" "square" "line"))
'(("POLYLINE" "2" "3") ("LINE" "4" "5") ("SQUARE" "6" "7" "8"))