Проверьте, есть ли строчные символы в строке - PullRequest
3 голосов

Мне нужно вернуть True или False

  • True если хотя бы один символ нижнего регистра
  • False без строчных букв

Я пытался сделать это с помощью функции цикла и лямбды Как то так

(defun check-lower-word (word)
    (loop
        for ch across word 
        ((lambda (c) (if (lower-case-p c) return T) ch)
    )
)

Мне нужен False, если никогда не работал "если"

Ответы [ 3 ]

6 голосов
/ 23 мая 2019

С предопределенной функцией вы можете использовать some ( ручной ):

CL-USER> (some #'lower-case-p "AbC")
T
CL-USER> (some #'lower-case-p "ABC")
NIL

Существует аналогичная операция для синтаксиса loop ( manual ):

CL-USER> (loop for x across "AbC" thereis (lower-case-p x))
T
CL-USER> (loop for x across "ABC" thereis (lower-case-p x))
NIL

Наконец, обратите внимание, что loop всегда возвращает nil, когда итерация завершается без получения результата, поэтому менее кратким использованием loop может быть:

CL-USER> (loop for x across "AbC" if (lower-case-p x) do (return t))
T
CL-USER> (loop for x across "ABC" if (lower-case-p x) do (return t))
NIL
2 голосов
/ 23 мая 2019

Ошибки кода

Ваш код не сбалансирован относительно скобок, в конце отсутствует закрывающая скобка:

(defun check-lower-word (word)
    (loop
        for ch across word 
        ((lambda (c) (if (lower-case-p c) return T) ch)
    )
) ; <-- closes "(loop"

Синтаксическая ошибка в вашем loop должна была вызвать ошибку, нет смысла писать выражение EXPR непосредственно в (loop for c across w EXPR), должно быть предшествующее do.

Литерал ((lambda (c) E) ch) может быть непосредственно записан как E, где каждый вхождения переменной c заменяется на ch, а именно:

(if (lower-case-p ch) return T)

Использование промежуточной буквальной лямбды здесь ничего не дает.

Кроме того, приведенное выше читается как: , если ch в нижнем регистре, значение if - это значение, связанное с переменной return, в противном случае это T . Вы действительно пропускаете парены около (return T). «Однорукий» (if T X) лучше всего записать как (when T X).

Другой подход

У вас уже есть пример с some и loop, вы также можете использовать короткое замыкание map:

(defun check-lower-word (word)
  (block nil
    (map ()
         (lambda (c)
           (when (lower-case-p c)
             (return t)))
         word)))

Вызов MAP с nil в качестве первого аргумента означает, что последовательность повторяется для эффектов и возвращает ноль. Для каждого символа в последовательности (список или вектор), когда символ в нижнем регистре, возвращают T. return выходит из итерации раньше, до блока NIL.

0 голосов

Я сделал это как

(defun check-lower-word (word)
    (block outer
        (loop
            for ch across word do
                (if (lower-case-p ch) (return-from outer T))
        )
    )
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...