2011-09-11 12 views
7

の要素の変動値Iは、単純な関数を見つける方法として、SO使用して嫌い、私は本当にこのどこかのような機能を見つけることができません。スキーム:リスト

リストを考える(1 2 3 4 5)、私はPerlの(PHPののと同等、Pythonの)(1 2 3 100 5)

おかげで、その結果

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

をたいと思います!

+4

これは、データ構造から望み、セルのランダムな再割り当てを望んでいる場合、おそらく本当にリストを必要としないと考えましたか?代わりに、おそらくベクトルでしょうか? –

答えて

7

あなたはそうのように、ガイルのlist-set!を書くことができます

(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でこれをしようとしました。)

+0

私は 'list-set!'を '勘違いする。これはスクリプトを 'chicken'に移植することができます。 – hpaulj

3

Guileには、ゼロベースのインデックスを使用して、正確にあなたが望むものを実行する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) 

これは言語標準の一部です。

+1

通常、Schemeの 'set!'は場所をサポートしていません。しかしSRFI 17がロードされていると(実装がサポートしている場合--- Guileは)、(set!(list-ref lst 3)100) 'を使用することができます。編集:おっと、それはギルでは動作しませんが、 '(セット!(caddrのlst)100)'はしません。 –

+0

私は、nthのSchemeに相当するのはlist-refだと思っていますが、残念ながら値は参照ではありません(少なくとも私の環境では) – amindfv

+0

注意「参照を返す」はSchemeまたはLispには存在しません。 CLの 'setf'がマクロレベルで動作する方法は、"返された参照 "で動作しません。同じことがSchemeのsrfi-17にも当てはまります。代わりに、 "返された参照"を使用せず、set関数を見つけるために 'set!' -ed関数を使います。 –

3

を任意のSRFIせずに標準関数を使用する:

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

私がかもしれ少し遅れましたが、私は別の答えを持っています。

機能プログラムパラダイムの一部は、可能であればデータを変更しないようにするように思われるようです。効率の理由から、ここで他の答えと一緒に行きたいと思うかもしれません。 (コードはチキンスキームと「missbehave」ライブラリを用いた試験で書かれている

(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)))))) 

(define (list-with lst idx val) 
    (if (null? lst) 
    lst 
    (cons 
     (if (zero? idx) 
     val 
     (car lst)) 
     (list-with (cdr lst) (- idx 1) val)))) 

次のテストを渡します。しかし、そうでない場合は、このような非変異機能を検討しかし、かなり移植性の高いSchemeのように思えます。)