Discussion:
Better way to write this function?
(too old to reply)
B. Pym
2024-09-10 06:37:35 UTC
Permalink
As part of a larger program I needed a function which given a number
(n) and a vector (row), returns the index into row of the n'th nil in
(defun nth-slot (n v)
"Find the nth nil cell in a vector v."
(loop with slots-seen = 0
for item across v
for idx from 0
counting (not item) into slots-seen
until (> slots-seen n)
finally (if (> slots-seen n) (return idx) (error "No slot"))))
Please take that inscrutal glop to comp.lang.loop. <g>
(defun nth-null-slot-index (n v &optional must-find-p &aux (nil-ct 0))
"Return the index of the nth nil cell in vector v"
(dotimes (x (length v) (when must-find-p (error "bzzzt")))
(when (null (elt v x))
(when (= n (incf nil-ct)) ;; [1]
(return-from nth-null-slot-index x)))))
(nth-null-slot-index 3 #(nil 1 2 nil 3 4 nil 5 nil nil))
=>6
The first nil found is considered to be number 1,
not number 0.

Gauche Scheme

(use gauche.generator)

;; "We don't need no stinkin' loops!"
(define (nth-null-slot-index n vec)
(list-ref
(generator->list
;; Gauche coerces the vector to a generator.
(gselect (grange 0) (gmap not vec)))
(- n 1)))


(nth-null-slot-index 3 #(#f a b #f c d #f e #f #f))
===>
6
B. Pym
2024-09-10 20:17:24 UTC
Permalink
Post by B. Pym
As part of a larger program I needed a function which given a number
(n) and a vector (row), returns the index into row of the n'th nil in
(defun nth-slot (n v)
"Find the nth nil cell in a vector v."
(loop with slots-seen = 0
for item across v
for idx from 0
counting (not item) into slots-seen
until (> slots-seen n)
finally (if (> slots-seen n) (return idx) (error "No slot"))))
Please take that inscrutal glop to comp.lang.loop. <g>
(defun nth-null-slot-index (n v &optional must-find-p &aux (nil-ct 0))
"Return the index of the nth nil cell in vector v"
(dotimes (x (length v) (when must-find-p (error "bzzzt")))
(when (null (elt v x))
(when (= n (incf nil-ct)) ;; [1]
(return-from nth-null-slot-index x)))))
(nth-null-slot-index 3 #(nil 1 2 nil 3 4 nil 5 nil nil))
=>6
The first nil found is considered to be number 1,
not number 0.
Gauche Scheme
(use gauche.generator)
;; "We don't need no stinkin' loops!"
(define (nth-null-slot-index n vec)
(list-ref
(generator->list
;; Gauche coerces the vector to a generator.
(gselect (grange 0) (gmap not vec)))
(- n 1)))
(nth-null-slot-index 3 #(#f a b #f c d #f e #f #f))
===>
6
Without using generators:

(define (nth-null-slot-index n vec)
(list-ref
(filter-map
(^(a b) (and b a))
(lrange 0)
(map not (vector->list vec)))
(- n 1)))

Loading...