[commodity-utils] refactor gnc:pricelist-price-find-nearest

instead of O(3n), this implementation is O(n)
This commit is contained in:
Christopher Lam 2019-07-21 20:35:28 +08:00
parent 1387c05f4d
commit e5b756fada

View File

@ -295,27 +295,21 @@ construct with gnc:make-gnc-monetary and gnc:monetary->string instead.")
;; pricelist comes from
;; e.g. gnc:get-commodity-totalavg-prices. Returns a <gnc-numeric> or,
;; if pricelist was empty, #f.
(define (gnc:pricelist-price-find-nearest
pricelist date)
(let* ((later (find (lambda (p)
(< date (car p)))
pricelist))
(earlierlist (take-while
(lambda (p)
(>= date (car p)))
pricelist))
(earlier (and (not (null? earlierlist))
(last earlierlist))))
(if (and earlier later)
(if (< (abs (- date (car earlier)))
(abs (- date (car later))))
(cadr earlier)
(cadr later))
(or
(and earlier (cadr earlier))
(and later (cadr later))))))
(define (gnc:pricelist-price-find-nearest pricelist date)
(let lp ((pricelist pricelist))
(cond
((null? pricelist) #f)
((null? (cdr pricelist)) (cadr (car pricelist)))
(else
(let ((earlier (car pricelist))
(later (cadr pricelist)))
(cond
((< (car later) date)
(lp (cdr pricelist)))
((< (- date (car earlier)) (- (car later) date))
(cadr earlier))
(else
(cadr later))))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Functions to get one price at a given time (i.e. not time-variant).