2016-08-31 3 views
-1

Ich habe 2 Arten von Listen mit Schlüssel-Wert-Paaren suchen:Funktion von Werten in verschiedenen Arten von Listen

(define pairs1 (list (list 1 2)(list 10 20)(list 100 200))) 
(define pairs2 (list (cons 1 2)(cons 10 20)(cons 100 200))) 

Ich mag suche nach Wert in beiden Arten von Listen mit einer Funktion. Ich habe versucht, folgende (‚cdr‘ in ein und ‚zweite‘ in anderen fn), aber sie arbeiten mit einer Liste jeder:

(define (assoc_val1 val spair) 
    (for/list ((item spair) #:when (equal? (cdr item) val)) 
     item)) 

(define (assoc_val2 val spair) 
    (for/list ((item spair) #:when (equal? (second item) val)) 
     item)) 

Kann ich eine Funktion haben, die für beide Arten von Listen funktioniert? Gibt es auch eine gute Verbindung, die den Unterschied zwischen (Liste 1 2), (Nachteile 1 2) und (1 2) erklärt?


Edit: Ändern der Antwort von @Sylwester vorgesehen, Funktion können sich auf beiden Listen erkennen und Arbeit:

(define (assoc2* haystack needle [is-equal? equal?]) 
    (if (list? (car haystack)) 
     (findf (λ (e) (is-equal? needle (second e))) haystack) 
     (findf (λ (e) (is-equal? needle (cdr e))) haystack) 
    )) 

(assoc2* pairs1 20) 
(assoc2* pairs2 20) 

Ausgang:

'(10 20) 
'(10 . 20) 
+1

Für Ihre letzte Frage: http://stackoverflow.com/questions/34984552/what-is-the-difference-between-quote-and-list – soegaard

+1

Zum ersten: Warum möchten Sie zwei Arten von Schlüssel-Wert haben Darstellungen. Wähle eins. – soegaard

+0

Danke für den Link, der hauptsächlich Listen- und Angebotsformulare behandelt. Irgendein Link für Liste gegen Nachteile Formen? Was ist der beste Weg, wenn man in einer Anwendung Schlüssel-Wert-Paare verwenden muss? – rnso

Antwort

1

Nur #:accessor als Schlüsselwort Parameter hinzufügen oder optionaler Parameter:

;; Fully compatible with assoc but allows for searching any part 
(define (assoc* haystack needle [is-equal? equal?] #:accessor [accessor car]) 
    (findf (λ (e) (is-equal? needle (accessor e))) haystack)) 

(assoc* pairs1 20 #:accessor cadr) ; ==> (10 20) 
(assoc* pairs2 20 #:accessor cdr) ; ==> (10 . 20) 
+0

Kann der Code erkennen, welche Art von Liste es ist und relevante Funktion anwenden? – rnso

+0

@mso Es kommt darauf an. Stellen Sie sich vor, Sie haben eine Assoziation mit Paarwerten, z. "((0. (0 0)) (1. (0 1)) (2. (1 0)) (3. (1 1)))". Wie Sie wissen, '(0. (0 0))' ist das gleiche wie '(0 0 0)' Wie also wäre es möglich zu bestimmen, ob die Elemente Paare oder Listen sind? Sie können nicht, aber wenn Sie wissen, dass die Werte ** nie ** Paare sind, dann könnten Sie es tun, aber es wird nicht mehr ein allgemeines Verfahren sein. – Sylwester

+0

Pl siehe meine Änderung Ihres Codes in der obigen Frage. Arbeitet seit (Nachteile 1 2) gibt falsch mit "Liste?" Funktion. – rnso

Verwandte Themen