2011-09-11 21 views
7

Basit fonksiyonlar bulmak için bir yol olarak SO kullanarak istemem, ama gerçekten bu her yerde böyle bir işlevi bulamıyorum: bir listeŞema: Listedeki bir elemanın değişim değeri

Verilen (1 2 3 4 5), Perl en (PHP en eşdeğer, Python en) (1 2 3 100 5)

teşekkür sonuçlanır

$a = array(1, 2, 3, 4, 5); 
$a[3] = 100; 

istiyorum!

+4

Bu, veri yapısının dışında kalmak istediğiniz işlevsellik, hücrelerin rastgele yeniden atanması gibi bir işlevse, belki de gerçekten bir liste istemediğinizi düşündünüz mü? ama bunun yerine belki bir vektör? –

cevap

7

Çok gibi Guile'ın list-set! yazabilirsiniz:

(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 bu çalıştı.)

+0

“list-set!' guile'. Bu, betiği "tavuk" a yönlendireyim. – hpaulj

3

Guile, sıfır tabanlı indeksler kullanarak tam olarak istediğiniz şeyi yapan list-set! adlı yerleşik bir işleve sahiptir.

(define a '(1 2 3 4 5)) 
(list-set! a 3 100) 

Bu ancak, standart Şeması olduğunu düşünmüyorum ve gerçekten verimli olmadığını bilmiyorum: senin Örneğin, olurdu. Ben bu dil standardının bir parçasıdır eminim

(define a2 #(1 2 3 4 5)) 
(vector-set! a2 3 100) 

: Bir sabit uzunluklu bir dizi için muhtemelen bir vektör kullanmalıdır.

+1

Normalde, Scheme'de 'set!' Yerleri desteklemiyor. Ancak, SRFI 17 yüklü olduğunda (uygulamanız destekliyorsa --- Guile yaparsa), isterseniz (set! (List-ref lst 3) 100) 'yi kullanabilirsiniz. EDIT: Oops, Guile'de çalışmıyor, ama '(set! (Caddr lst) 100)' yapar. –

+0

Sanırım program eşdeğeri liste-ref'dir, maalesef referans olmayan bir değer döndürür (en azından benim ortamımda) – amindfv

+0

Not thaht "bir referans döndürür", Şema veya Lisp'de bulunmayan bir şeydir. CL'nin 'setf''inin çalışma şekli makro seviyededir, bazı" iade edilen referans "üzerinde çalışmaz. Aynı şemada srfi-17 için de geçerli: "geri verilen bir referans" kullanmıyor, bunun yerine bir setter fonksiyonu bulmak için 'set!' -ed fonksiyonunu kullanıyor. –

3

herhangi srfi olmadan standart fonksiyonları kullanarak:

(set-car! (list-tail lst k) val) 
3

Ben olabilir biraz geç ama farklı bir cevabım var. Fonksiyonel program paradigmasının bir kısmı, mümkün olduğunda verilerin değiştirilmesinden kaçınmaya çalışmak gibi görünmektedir. Verimlilik nedeniyle burada diğer cevaplarla gitmek isteyebilirsiniz. Ama aksi halde, bu gibi olmayan bir değişen yapısıyla işleve bakalım:

aşağıdaki testleri geçer
(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)))))) 

(kod Tavuk Planı yazılmış ve "missbehave" kütüphane ile testler Ancak, oldukça portatif bir şema gibi görünüyor.)