How can I return a list with different values?

If I have the following list:

(define thelist '(0 1 0 0 7 7 7)) 

How to write a function that returns a new list in which the value in the requested cell is replaced.

Example:

 (set-cell thelist 2 4) 

This will return a new list with the same values, but in cell (2) there will be a value of 4 instead of 1:

 (0 4 0 0 7 7 7) 
+4
source share
5 answers

Although you can implement the requested functionality with lists, a natural way to solve this problem is to use vector and remember that in the indexes, schemes start at 0 (so the second argument to vector-set! Is 1 , not a 2 ):

 (define thevector (vector 0 1 0 0 7 7 7)) ; thevector is #(0 1 0 0 7 7 7) (vector-set! thevector 1 4) ; thevector is #(0 4 0 0 7 7 7) 

Now, if you definitely need to use a list, something like this will work:

 (define (set-cell lst idx val) (cond ((null? lst) '()) ((zero? idx) (cons val (cdr lst))) (else (cons (car lst) (set-cell (cdr lst) (sub1 idx) val))))) 

And you would call it like this:

 (define thelist '(0 1 0 0 7 7 7)) (set-cell thelist 1 4) > (0 4 0 0 7 7 7) 

Again, I use 0-based indexing, like convention. Also note that thelist not been changed; instead, set-cell returns a new list with a modification.

+4
source

HtDP provides a truly concrete methodology to solve this problem. For this task, your task is to write a template for lists, and then look at it until you see what the arguments for the recursive call should be and what the results will be. I hope that you solved the problem of warming up in lists - calculate the length of the list, count the number 6 in the list, etc.

+5
source

Other people mentioned the 0-based index convention. Then I will use 0-based indexes.

The other answers you received are incorrect, given how you stated your problem. I will give a key point in your question (my emphasis):

This will return a new list with the same values, but in cell (2) there will be a value of 4 instead of 1.

The answers given to you change the list in place, rather than returning the newly built list, leaving the original intact!

Here's the correct (albeit non-optimal) solution:

 (define (set-list index new-value list) (if (= index 0) (cons new-value (cdr list)) (cons (car list) (set-list (- index 1) new-value (cdr list)))))) 

I did not bother to include error checking here (for example, if someone goes through an empty list or a list with too few elements relative to index or a negative index).

0
source

Here's an approach using a helper function that starts a count from 0. At each recursion, the count grows and the list shrinks.

If the desired index is hit, recursion may stop. If it reaches the end of the list without clicking the index, the original list is returned.

 (define (set-cell ls ind val) (define (aux c ls) (cond ((null? ls) ls) ((= c ind) (cons val (cdr ls))) (else (cons (car ls) (aux (+ c 1) (cdr ls)))))) (aux 0 ls)) 
0
source

What a mess above! Keep it simple: the circuit has a list! for this. Example:

 (define ls (list 1 2 3 4 5)) (list-set! ls 0 "new") (list-set! ls 3 "changed") (list-ref ls 0) => "new" ls => '("new" 2 3 "changed" 5) 

However, you can limit the purpose of lists. Vectors are faster for this, since you don't have to go through the previous elements. Use lists when you cannot specify the length before the start of construction or when the length will be constantly changing.

-1
source

Source: https://habr.com/ru/post/1388812/


All Articles