12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- (library (vector-procs)
- (export vector-filter)
- (import (rnrs base)
- (only (guile)
- lambda* λ)
- ;; SRFIs
- ;; srfi-43 for vector procs
- (srfi srfi-43)))
- (define vector-copy-elements!
- (λ (source target indices)
- "Copy elements from vector SOURCE at INDICES to vector TARGET."
- ;; Iteratively copy all elements, which are matching.
- (let iter ([remaining-indices indices]
- [target-next-ind 0])
- (cond
- ;; If no more indices are left, return the new vector.
- [(null? remaining-indices) target]
- [else
- ;; Copy over the value from the source vector.
- (vector-set! target
- target-next-ind
- (vector-ref source (car remaining-indices)))
- ;; Continue with the rest of the indices.
- (iter (cdr remaining-indices)
- (+ target-next-ind 1))]))))
- (define vector-filter
- (λ (pred vec)
- "Filter a vector and return the filtered vector."
- (define iter
- (λ (index entries-found-count indices)
- "Iterate over the whole vector from last to first
- element, keeping track of elements, for which the predicate
- pred is true. Build a list in reverse, which will be in the
- order of going from first to last element of the vector,
- without the need to reverse it later."
- (cond
- ;; If the whole vector has been searched for
- ;; matching elements, return the indices of
- ;; matching elements and the number of matching
- ;; elements found.
- [(< index 0)
- (values indices entries-found-count)]
- ;; Otherwise continue iterating over the vector.
- [else
- (let ([vec-elem (vector-ref vec index)])
- (cond
- ;; Case for matching elements.
- [(pred vec-elem)
- (iter (- index 1)
- (+ entries-found-count 1)
- (cons index indices))]
- [else
- (iter (- index 1)
- entries-found-count
- indices)]))])))
- (let-values ([(indices entries-found-count)
- (iter (- (vector-length vec) 1)
- 0
- '())])
- (vector-copy-elements! vec
- (make-vector entries-found-count
- 'undefined)
- indices))))
|