[racket] This is too clumsy. Is there a better way?

From: Danny Yoo (dyoo at hashcollision.org)
Date: Fri Jul 13 09:31:14 EDT 2012

> (define (all-lower-case? str)
>   (not (memq #t
>              (map (lambda (i)
>                     (if (and (char-alphabetic? i) (char-upper-case? i))
>                       #t #f))
>                   (string->list str)))))
>
> This looks rather clumsy to me.

It's also named "all-lower-case?", but appears to return true only if
it's all upper case.  :)



>  I am converting the string into  a list of characters, then I check the case of each character
> and issue the requisite verdict.  It seems to me that there
> ought to be a neater way.  Any suggestions?

You can use a for/and loop across the characters of the string, like this:

;;;;;;;;;;;;;;;;;;;;;;;
(define (all-lower-case? str)
  (for/and ([ch str])
    (and (char-alphabetic? ch) (char-lower-case? ch))))
;;;;;;;;;;;;;;;;;;;;;;;

This function actually acts on anything that's a sequence.  If you
want to specialize it to strings for better efficiency, use (in-string
...):

;;;;;;;;;;;;;;;;;;;;;;;
(define (all-lower-case? str)
  (for/and ([ch (in-string str)])
    (and (char-alphabetic? ch) (char-lower-case? ch))))
;;;;;;;;;;;;;;;;;;;;;;;


See the Guide about for loops for more details:

    http://docs.racket-lang.org/guide/for.html

Posted on the users mailing list.