开发者

Abstracting functions / avoiding repetition in functions

开发者 https://www.devze.com 2023-02-02 12:33 出处:网络
I need some advice on abstracting the find and check-callback functions. The code works fine, but it seems that there is a lot of unnecessary repetition. Is there a more elegant way to re-write them?

I need some advice on abstracting the find and check-callback functions. The code works fine, but it seems that there is a lot of unnecessary repetition. Is there a more elegant way to re-write them?

;; Model
(define-struct contact (name phone))
(define phonebook (list (make-contact 'adam 5551212)
                        (make-contact 'brian 5552323)
                        (make-contact 'chris 5558888)))

;; find: (string->symbol, string->number) item (listof items) -> symbol/number/false
(define (find type item pb)
  (cond
    [(empty? pb) false]
    [(equal? (string->symbol item) (contact-name (first pb))) (contact-phone (first pb))]
    [(equal? (string->number item) (contact-phone (first pb))) (contact-name (first pb))]
    [else (find type item (rest pb))]))

;; Controller
(define (check-callback b)
  (cond
    [(number? (find str开发者_如何学Cing->symbol (text-contents a-text-field) phonebook))
     (draw-message a-msg (number->string (find string->symbol (text-contents a-text-field) phonebook)))]
    [(symbol? (find string->number (text-contents a-text-field) phonebook))
     (draw-message a-msg (symbol->string (find string->number (text-contents a-text-field) phonebook)))]
    [else (draw-message a-msg "Not found")]))


;; View
(define a-text-field
  (make-text "Enter a name or phone number"))

(define a-msg
  (make-message ""))

(define a-button
  (make-button "Search" check-callback))

(create-window
 (list (list a-text-field)
       (list a-button)
       (list a-msg)))


Since the type variable is not used, I omitted it from the code and made some refactoring:

;; find
(define (find item pb)
  (let* ((first-pb (first pb))
         (name (contact-name first-pb))
         (phone (contact-phone first-pb)))
    (cond
      [(empty? pb) #f]
      [(equal? (string->symbol item) name) phone]
      [(equal? (string->number item) phone) name]
      [else (find item (rest pb))])))

;; Controller
(define (check-callback pb)
  (let ((res (find (text-contents a-text-field) pb)))
    (draw-message a-msg
                  (cond
                    [(number? res) (number->string res)]
                    [(symbol? res) (symbol->string res)]
                    [else "Not found"]))))

Or you could just convert your name and phone to string at once:

;; find
(define (find item pb)
  (let* ((first-pb (first pb))
         (name (contact-name first-pb))
         (phone (contact-phone first-pb)))
    (cond
      [(empty? pb) #f]
      [(equal? (string->symbol item) name) (number->string phone)]
      [(equal? (string->number item) phone) (symbol->string name)]
      [else (find item (rest pb))])))

;; Controller
(define (check-callback pb)
  (let ((res (find (text-contents a-text-field) pb)))
    (draw-message a-msg
                  (if (res)
                    res
                    "Not found"))))
0

精彩评论

暂无评论...
验证码 换一张
取 消