Ivan Prodanov
Ivan Prodanov

Reputation: 35502

how to ignore inner lists in scheme?

I wrote a procedure that gets every value from a list and returns a list where every value is -1(for example)

(define (Set-list a val)
  (if ( null? a) (list)
    (append (list val) (Set-list (cdr a) val))
))

(Set-list '(2 3 4) -1) //returns '(-1 -1 -1)
(Set-list '(A(2 3) B(2 3) C(2 3)) -1) // returns '(-1 -1 -1 -1 -1 -1)

how do i make it return -1 -1 -1? I don't want to get the inner members of the list?

Upvotes: 0

Views: 312

Answers (4)

grgizem
grgizem

Reputation: 310

If you want to make a value's list which length is the same with given lists length,

(define (set-list list value)
    (build-list (length list) (lambda (x) value)))

so,

(set-list '(2 3 4) -1) //returns '(-1 -1 -1)
(set-list '(A (2 3) B (2 3) C (2 3)) -1) // returns '(-1 -1 -1 -1 -1 -1)
(set-list '(2 3 4) -2) //returns '(-2 -2 -2)
(set-list '(A (2 3) B (2 3) C (2 3)) -2) // returns '(-2 -2 -2 -2 -2 -2)

Upvotes: 0

Óscar López
Óscar López

Reputation: 236004

Maybe you're confusing how lists work in Scheme. This list: '(A(2 3) B(2 3) C(2 3)) is exactly the same as this list: '(A (2 3) B (2 3) C (2 3)). That is, it's a six-element list. If you want to treat the combination of symbol-and-numbers as a single element, pack them together in a single list: '((A 2 3) (B 2 3) (C 2 3))

As a side note, the way the set-list procedure is written is not idiomatic, in particular using append is not the best way to put elements at the head when building a list, use cons for that. This is a better way to write the procedure:

(define (set-list a val)
  (if (null? a)
      '()
      (cons val
            (set-list (cdr a) val))))

Now, following my advice above, here's how it would work:

(set-list '((A 2 3) (B 2 3) (C 2 3)) -1)
=> '(-1 -1 -1)

UPDATE:

Now, if there really isn't a misunderstanding with the way lists work and you just want to replace all sublists in a list with a given value, this will work:

(define (set-list a val)
  (build-list (length (filter (negate list?) a))
              (lambda (x) val)))

Upvotes: 1

C. K. Young
C. K. Young

Reputation: 223003

Since Anton mentioned about an idiomatic solution, here is my idiomatic solution in Racket (I believe the use of higher-order functions, like map, filter-not, and arguably const is more idiomatic than manually looping and filtering). :-)

(define (set-list lst val)
  (map (const val) (filter-not list? lst)))

(Racket does provide filter-map but it applies the filter and map in the opposite order from what we want to do.)

Upvotes: 1

Anton Kovalenko
Anton Kovalenko

Reputation: 21507

Here's my attempt (probably not idiomatic scheme, and please note that doing it with append is wrong anyway). I assume that you want to skips sublists entirely, as you explained in comments.

(define (Set-list a val)
  (if (null? a)
      (list)     
      (append (if (list? (car a))
                  (list)
                  (list val))
              (Set-list (cdr a) val))))

Upvotes: 0

Related Questions