joe
joe

Reputation: 53

Scheme function returns up-to-first-number

I want to write a scheme function that takes a list as its input and returns a list containing all the elements up to the first numeric element in the input list.

Here is an example:

(up-to-first-number '(a b c d 1 2 3)) ; returns (a b c d)

How can I do this?

Upvotes: 4

Views: 787

Answers (2)

Trixie the Cat
Trixie the Cat

Reputation: 317

(define (up-to-first-number list)
  (cond
    ;;if the list is null return an empty list
    ((null? list)
      '())
      ;;if the first element is a number then there are no preceeding 
      ;;letters in the list so return an empty list
      ((number? (car list)) '())
      ;;else the first element is not a number so add that element
      ;;to a new list and recursively call method on the remaining 
      ;;elements in the list
      (else (cons (car list) (up-to-first-number (cdr list) )))))

Upvotes: 0

Óscar López
Óscar López

Reputation: 235984

Look for an existing procedure in your interpreter that implements a similar functionality. For instance, in Racket we can use takef - the following simply states that all elements that are not numbers are taken from the list, and we stop when we find the first number:

(define (up-to-first-number lst)
  (takef lst (negate number?)))

Even if you're using a different interpreter, you can always use SRFI-1's take-while for a similar effect:

(require srfi/1) ; import the library, read your interpreter's documentation

(define (up-to-first-number lst)
  (take-while (lambda (x) (not (number? x))) lst))

As a last resort, you can write an implementation by hand - it's real simple and I don't want to spoil the fun, so I'll only give you some hints. Fill-in the blanks with the appropriate expressions:

(define (up-to-first-number lst)
  (if (or <???>   ; if either the list is empty
          <???>)  ; or the first element is a number
      <???>       ; then return the empty list
      (cons <???> ; otherwise cons the first element
            (up-to-first-number <???>)))) ; and advance the recursion

It doesn't matter what implementation you choose, you can test that it works as expected:

(up-to-first-number '(a b c d 1 2 3)) 
=> '(a b c d)

Upvotes: 5

Related Questions