Search code examples
stringlistpositionschemeracket

Scheme: How to find a position of a char in a string


I am trying to find the index of a string where it is equal to a certain character, but I can seem to figure it out. This is what I got so far, but its not working...

(define getPos 
  (lambda ()
    (define s (apply string-append myList))
    (getPosition pos (string->list s))))

(define getPosition 
  (lambda (position s)
    (if (and (< position (length s)) (equal? (car s) #\space)) 
        ((set! pos (+ pos 1)) (getPosition (cdr s) pos));increment the positon and continue the loop
        pos)));else

(define length
  (lambda (s);the value s must be coverted to a string->list when passed in
    (cond
      ((null? s) 0)
      (else (+ 1 (length (cdr s)))))))

Solution

  • The solution is simple: we have to test each char in the list until either we run out of elements or we find the first occurrence of the char, keeping track of which position we're in.

    Your proposed solution looks weird, in Scheme we try to avoid set! and other operations that mutate data - the way to go, is by using recursion to traverse the list of chars. Something like this is preferred:

    (define (getPosition char-list char pos)
      (cond ((null? char-list) #f)              ; list was empty
            ((char=? char (car char-list)) pos) ; we found it!
            (else (getPosition (cdr char-list) char (add1 pos))))) ; char was not found
    

    For 0-based indexes use it like this, converting the string to a list of chars and initializing the position in 0:

    (getPosition (string->list "abcde") #\e 0)
    => 4
    

    Of course, we can do better by using existing procedures - here's a more idiomatic solution:

    (require srfi/1) ; required for using the `list-index` procedure
    
    (define (getPosition string char)
      (list-index (curry char=? char) 
                  (string->list string)))
    
    (getPosition "abcde" #\e)
    => 4