Come scrivere la funzione media per questa struttura dati nello Schema / Lisp?
-
16-09-2019 - |
Domanda
Voglio trovare il prezzo di un nuovo elemento sulla base dei prezzi medi di oggetti simili.
Get-k-simile utilizza la funzione K-vicini vicini, ma mi restituisce questo output
((list rating age price) proximity)
.
For example, 2-similar would be:
(((5.557799748150248 3 117.94262493533647) . 3.6956648993026904)
((3.0921378389849963 7 75.61492560596851) . 5.117886776721699))
Ho bisogno di trovare il prezzo medio degli oggetti simili. cioè media di 117 e 75. C'è un modo migliore per iterare? La mia funzione sembra troppo brutto.
(define (get-prices new-item)
(define (average-prices a-list)
(/ (cdr
(foldl (λ(x y) (cons (list 0 0 0)
(+ (third (car x)) (third (car y)))))
(cons (list 0 0 0) 0)
a-list))
(length a-list)))
(let ((similar-items (get-k-similar new-item)))
(average-prices similar-items)))
Soluzione
È possibile fare la cosa semplice e basta tirare fuori ogni terzo valore:
(define (average-prices a-list)
(/ (apply + (map fourth a-list)) (length a-list)))
Questo è un po 'inefficiente, dato che produce una lista intermedia, e la mia ipotesi è che questo è il motivo per cui si è tentato foldl
. Ecco il modo giusto per farlo:
(define (average-prices a-list)
(/ (foldl (lambda (x acc) (+ (third x) acc)) 0 l)
(length a-list)))
C'è ancora un'inefficienza minorenne - length
sta facendo una seconda scansione - ma questo è qualcosa che non si deve preoccuparsi in quanto si avrebbe bisogno alcuni davvero lunghe liste di ottenere qualsiasi rallentamento visibile .
Altri suggerimenti
Common Lisp
(/ (reduce '+ a-list :key 'caddar) (length a-list))
o
(loop for ((nil nil e) . nil) in a-list
count e into length
sum e into sum
finally (return (/ sum length)))