Scheme:更改列表中元素的值

ami*_*dfv 7 lisp scheme list

我讨厌使用SO作为查找简单函数的方法,但我真的找不到这样的函数:

给出一个列表(1 2 3 4 5),我想要相当于(PHP的,Perl的,Python的)

$a = array(1, 2, 3, 4, 5);   
$a[3] = 100;  
Run Code Online (Sandbox Code Playgroud)

结果如何(1 2 3 100 5)

谢谢!

Ros*_*ews 7

你可以写下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)
Run Code Online (Sandbox Code Playgroud)

(在DrRacket中试过这个.)


new*_*cct 5

使用没有任何 SRFI 的标准函数:

(set-car! (list-tail lst k) val)
Run Code Online (Sandbox Code Playgroud)


Ste*_*tis 5

我可能有点晚了,但我有不同的答案。

函数式程序范式的一部分似乎是尽可能避免修改数据。出于效率原因,您可能希望在此处使用其他答案。但除此之外,请考虑一个非变异函数,例如:

(define (list-with lst idx val)
  (if (null? lst)
    lst
    (cons
      (if (zero? idx)
        val
        (car lst))
      (list-with (cdr lst) (- idx 1) val))))
Run Code Online (Sandbox Code Playgroud)

通过以下测试:

(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))))))
Run Code Online (Sandbox Code Playgroud)

(代码是用 Chicken Scheme 编写的,并且使用“missbehave”库进行测试。但它似乎非常便携。)