我刚刚开始学习球拍。
我有此代码:
#lang racket
(define l1 '(1 2 3 4))
(car l1)
(cdr l1)
(car l1)
返回1。
(cdr l1)
返回'(2 3 4)
是否有返回'(1 2 3)
的函数?
我已经尝试过了:
#lang racket
(define l1 '(1 2 3 4))
(map
(lambda (l i)
(if (not (= i (sub1 (length l1)))) l '()))
l1 (range 0 (length l1)))
但是,它返回:'(1 2 3 ())
我也尝试过:
#lang racket
(define l1 '(1 2 3 4))
(map
(lambda (l i)
(cond ((not (= i (sub1 (length l1)))) l )))
l1 (range 0 (length l1)))
但是,它返回:'(1 2 3 #<void>)
答案 0 :(得分:3)
backgroundSoundService
函数始终返回与输入长度相同的列表。您需要一个比其输入短的输出列表。您正在寻找的功能通常称为map
:
but-last
答案 1 :(得分:2)
这样的事情怎么样?
(define (myCdr l)
(if (not (pair? (cdr l)))
'()
(cons (car l) (myCdr (cdr l)))
)
)
答案 2 :(得分:2)
length
通常是Scheme中的反模式,因为需要读取整个列表才能获得结果。 W. Ness指出map
不会改变列表的结构,并且filter
的行为基于列表的 values ,都不符合您的需求。
您可以使用直接递归来计算列表的init
,而不是首先或笨拙地应用库函数来进行潜在的昂贵计算-
(define (init l)
(cond ((null? l)
(error 'init "cannot get init of empty list"))
((null? (cdr l))
null)
(else
(cons (car l)
(init (cdr l))))))
(init '(a b c d e)) ;; '(a b c d)
(init '(a)) ;; '(a)
(init '()) ;; init: cannot get init of empty list
或仅使用一个reverse
-
(define (init l)
(let loop ((acc null)
(l l))
(cond ((null? l)
(error 'init "cannot get init of empty list"))
((null? (cdr l))
(reverse acc))
(else
(loop (cons (car l) acc)
(cdr l))))))
(init '(a b c d e)) ;; '(a b c d)
(init '(a)) ;; '(a)
(init '()) ;; init: cannot get init of empty list
最后是不使用length
或 reverse
的尾递归形式。有关其工作原理的更多直观信息,请参见"How do collector functions work in Scheme?"-
(define (init l (return identity))
(cond ((null? l)
(error 'init "cannot get init of empty list"))
((null? (cdr l))
(return null))
(else
(init (cdr l)
(lambda (r)
(return (cons (car l) r)))))))
(init '(a b c d e)) ;; '(a b c d)
(init '(a)) ;; '(a)
(init '()) ;; init: cannot get init of empty list
答案 3 :(得分:2)
还有一个,通过压缩:
#lang racket
(require srfi/1)
(define (but-last-zip xs)
(if (null xs)
xs ; or error, you choose
(map (lambda (x y) x)
xs
(cdr xs))))
这是另一个,模拟通过列表进行追加过滤,其中空列表会自行消失:
(define (but-last-app xs)
(if (null? xs)
xs
(let ((n (length xs)))
(apply append ; the magic
(map (lambda (x i)
(if (= i (- n 1)) '() (list x)))
xs
(range n))))))
或者我们可以直接使用decorate--filter--unecorate,这甚至是更多的代码!
(define (but-last-fil xs)
(if (null? xs)
xs
(let ((n (length xs)))
(map car
(filter (lambda (x) (not (null? x)))
(map (lambda (x i)
(if (= i (- n 1)) '() (list x)))
xs
(range n)))))))
答案 4 :(得分:1)
这里是另一种选择,假设列表是非空的。它高效(它对列表执行一次传递),并且没有比这更简单的了!
(define (delete-last lst)
(drop-right lst 1))
(delete-last '(1 2 3 4))
=> '(1 2 3)
答案 5 :(得分:1)
这里等同于Will Ness's beautiful but-last-zip
,它不依赖于球拍中的srfi/1
:没有srfi/1
时,球拍的map
坚持认为其所有参数的长度都相同(实际上是R5RS版本),但是在其他Lisps中,通常在最短列表的末尾终止该函数。
此函数使用Racket的for/list
,并在假设空列表的结果为空列表的情况下进行连接。
#lang racket
(define (but-last-zip xs)
(for/list ([x xs] [y (if (null? xs) xs (rest xs))])
x))
我认为Will的版本更纯净:在我看来,将功能映射到事物上是非常Lisp的事情,而for/list
对我来说则不太那么狡猾。此版本的唯一优点是它不需要模块。
答案 6 :(得分:0)
我自己的使用递归的解决方案:
//
// ContainerTestViewController.swift
//
import UIKit
// protocol / delegate pattern
protocol ABDelegate: class {
func myButtonWasTapped()
}
// "main" view controller conforms to ABDelegate protocol
class ContainerTestViewController: UIViewController, ABDelegate {
var vcA: ViewControllerA?
var vcB: ViewControllerB?
// this will be called by the code in ViewControllerA
func myButtonWasTapped() {
// call func in ViewControllerB
vcB?.doIncrement()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// if this is the embedded ViewControllerA
if let vc = segue.destination as? ViewControllerA {
// set self as the ABDelegate in ViewControllerA
vc.theDelegate = self
// keep a reference in case we want to access it
self.vcA = vc
}
// if this is the embedded ViewControllerB
if let vc = segue.destination as? ViewControllerB {
// keep a reference so we can call its doIncrement() func
self.vcB = vc
}
}
}
class ViewControllerA: UIViewController {
var theDelegate: ABDelegate?
@IBAction func incTapped(_ sender: Any) {
// call the func in the delegate
theDelegate?.myButtonWasTapped()
}
}
class ViewControllerB: UIViewController {
@IBOutlet var theLabel: UILabel!
var theValue = 0
override func viewDidLoad() {
super.viewDidLoad()
theLabel.text = String(theValue)
}
func doIncrement() -> Void {
theValue += 3
theLabel.text = String(theValue)
}
}
另一个使用#lang racket
(define but-last
(lambda (l)
(cond ((null? (cdr l)) '())
(else (cons (car l) (but-last (cdr l)))))))
和filter-not
的解决方案:
map