2011-01-06 9 views
1

Ich brauche einen Hinweis auf die Abstraktion der find und check-callback Funktionen. Der Code funktioniert gut, aber es scheint, dass es viele unnötige Wiederholungen gibt. Gibt es eine elegantere Möglichkeit, sie neu zu schreiben?Abstrahieren Funktionen/Vermeidung von Wiederholungen in Funktionen

;; 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 string->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))) 

Antwort

1

Da die type Variable nicht verwendet wird, ich weggelassen es aus dem Code und machte einige 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"])))) 

Oder Sie könnten nur auf einmal Ihren Namen und Telefon Zeichenfolge konvertieren:

;; 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

Danke Yasir. Ich werde von deinem Beispiel lernen. – Greenhorn

+0

@Greenhorn: Du bist ganz herzlich willkommen ;-) –

+1

@Greenhorn. Die verbleibende Komplexität ist das Ergebnis Ihrer Entscheidung, den Namen als Symbol und das Telefon als Nummer zu speichern. Beide als String zu speichern würde die Möglichkeit bieten, dies dramatisch zu vereinfachen, da alle Telefonbuchfelder generisch behandelt werden können. Plus in der Praxis sind Telefonnummern nicht wirklich Zahlen, sie sind Zeichenketten. Selbst wenn Sie ein oder zwei Felder hätten, die nicht als Zeichenfolgen gespeichert werden sollen, könnten Sie eine Möglichkeit bereitstellen, sie in Zeichenfolgen umzuwandeln (wie Sie es bereits für Benutzereingaben aus Zeichenfolgen konvertieren müssen). Dann könnte der Code, der auf Gleichheit überprüft und der Ansicht angezeigt wird, diese To-Zeichenfolge verwenden. –

Verwandte Themen