[英]Scheme: change value of an element in a list
我讨厌使用SO作为查找简单函数的方法,但我真的找不到这样的函数:
给出一个列表(1 2 3 4 5),我想要相当于(PHP的,Perl的,Python的)
$a = array(1, 2, 3, 4, 5);
$a[3] = 100;
结果如何(1 2 3 100 5)
谢谢!
你可以写list-set!
Guile,像这样:
(define a (list 1 2 3 4)) ; a is '(1 2 3 4)
(define (list-set! list k val)
(if (zero? k)
(set-car! list val)
(list-set! (cdr list) (- k 1) val)))
(list-set! a 2 100) ; a is '(1 2 100 4)
(在DrRacket中试过这个。)
Guile有一个名为list-set!
的内置函数list-set!
这完全符合您的要求,使用从零开始的索引。 对于您的示例,您将拥有:
(define a '(1 2 3 4 5))
(list-set! a 3 100)
我不认为这是标准方案,但我不知道它是否真的有效。 对于固定长度的数组,您应该使用向量:
(define a2 #(1 2 3 4 5))
(vector-set! a2 3 100)
我很确定这是语言标准的一部分。
使用没有任何SRFI的标准功能:
(set-car! (list-tail lst k) val)
我可能有点晚了,但我有一个不同的答案。
功能程序范例的一部分似乎是尽可能避免修改数据。 出于效率原因,您可能希望在此处使用其他答案。 但除此之外,请考虑一个非变异函数,例如:
(define (list-with lst idx val)
(if (null? lst)
lst
(cons
(if (zero? idx)
val
(car lst))
(list-with (cdr lst) (- idx 1) val))))
通过以下测试:
(describe "a function that returns a list with a 'changed' value"
(it "can modify the edges of lists without having 1-off errors"
(expect (list-with '(1 2 3 4 5) 0 99) (be equal? '(99 2 3 4 5)))
(expect (list-with '(1 2 3 4 5) 4 99) (be equal? '(1 2 3 4 99))))
(it "has something to do with creating new lists"
(expect (list-with '(1 2 3 4 5) 2 99) (be equal? '(1 2 99 4 5))))
(it "doesnt just modify the contents of the original list"
(let ((a '(1 2 3 4 5)))
(list-with a 2 99)
(expect a (be equal? '(1 2 3 4 5))))))
(代码用Chicken Scheme编写,测试用“missbehave”库。但它似乎是非常便携的Scheme。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.