如何在Racket中获取列表指定起始到结束元素的子列表
实现指定起始和结束元素的列表截取函数
首先把水果列表单独抽出来,代码会更清晰易维护:
(define fruit-list '("Apple" "Pear" "Peach" "pineapple" "dragon fruit" "blue berry" "mango" "strawberry"))
你之前用member实现了从指定元素到末尾的功能,现在要扩展到截取到指定结束元素,核心分两步走:
- 先获取从起始元素开始的子列表
- 从这个子列表里截取到结束元素为止的部分
第一步:写辅助函数截取到结束元素
写一个递归函数take-until,它会遍历列表,收集元素直到遇到目标结束元素(包含该元素):
(define (take-until target lst) (cond ((null? lst) '()) ; 列表为空时返回空 ((equal? (car lst) target) (list target)) ; 找到结束元素,返回仅包含它的列表 (else (cons (car lst) (take-until target (cdr lst)))))) ; 否则把当前元素加入结果,继续处理剩余列表
第二步:组合成最终函数
把member和take-until结合,就得到了从起始到结束元素的截取函数:
(define (sub-fruits start end) (take-until end (member start fruit-list)))
测试效果
调用(sub-fruits "Peach" "blue berry"),会得到预期结果:
'("Peach" "pineapple" "dragon fruit" "blue berry")
为什么之前用的filter、sort、range没用?
filter是过滤符合条件的元素,但无法保证元素的连续顺序,也不会在遇到结束元素时停止sort是对列表排序,会打乱原列表的顺序,完全不符合需求range是生成数值范围,和字符串元素的列表完全不相关
边界情况说明
如果起始元素在结束元素之后(比如(sub-fruits "mango" "Peach")),member返回的子列表里找不到结束元素,take-until会返回从起始元素到列表末尾的所有元素。如果需要处理这种非法输入,可以在函数里加判断,检查end是否在起始后的子列表中,再决定返回结果。
内容的提问来源于stack exchange,提问作者Azcio
相关产品推荐
相关产品推荐

