η-reduce icr:make-bysetpos-filter

This commit is contained in:
Mattias Engdegård 2026-03-02 17:10:04 +01:00
parent 9a092fd74e
commit b223f825f6
2 changed files with 23 additions and 26 deletions

View file

@ -953,8 +953,8 @@ BYSECOND=... clause; see `icalendar-recur' for the possible values."
(BYMINUTE (icr:refine-byminute interval values vtimezone))
(BYSECOND (icr:refine-bysecond interval values vtimezone))))
(defun icr:make-bysetpos-filter (setpos)
"Return a filter on values for the indices in SETPOS.
(defun icr:bysetpos-filter (setpos recurrences)
"Filter RECURRENCES on values for the indices in SETPOS.
SETPOS should be a list of positive or negative integers between -366
and 366, indicating a fixed index in a set of recurrences for *one
@ -963,10 +963,8 @@ an `icalendar-recur'. For example, in a YEARLY recurrence rule with an
INTERVAL of 1, the SETPOS represent indices in the recurrence instances
generated for a single year.
The returned value is a closure which can be called on the list of
recurrences for one interval to filter it by index."
(lambda (dts)
(let* ((len (length dts))
The returned value is RECURRENCES filtered by index."
(let* ((len (length recurrences))
(keep-indices (mapcar
(lambda (pos)
;; sequence indices are 0-based, POS's are 1-based:
@ -975,13 +973,14 @@ recurrences for one interval to filter it by index."
(1- pos)))
setpos))
(r nil)
(i 0))
(i 0)
(dts recurrences))
(while dts
(when (memq i keep-indices)
(push (car dts) r))
(incf i)
(pop dts))
(nreverse r))))
(nreverse r)))
(defun icr:refine-from-clauses (interval recur-value dtstart
&optional vtimezone)
@ -1225,8 +1224,7 @@ retrieved on subsequent calls with the same arguments."
(keep-indices (ical:recur-by* 'BYSETPOS recur-value))
(pos-recs
(if keep-indices
(funcall (icr:make-bysetpos-filter keep-indices)
sub-recs)
(icr:bysetpos-filter keep-indices sub-recs)
sub-recs))
;; Remove any recurrences before DTSTART or after UNTIL
;; (both of which are inclusive bounds):

View file

@ -117,13 +117,12 @@ END:VTIMEZONE
;; Tests for basic functions:
(ert-deftest ict:recur-bysetpos-filter ()
"Test that `icr:make-bysetpos-filter' filters correctly by position"
"Test that `icr:bysetpos-filter' filters correctly by position"
(let* ((t1 (list 1 1 2024))
(t2 (list 2 1 2024))
(t3 (list 12 30 2024))
(dts (list t1 t2 t3))
(filter (icr:make-bysetpos-filter (list 1 -1)))
(filtered (funcall filter dts)))
(filtered (icr:bysetpos-filter (list 1 -1) dts)))
(should (member t1 filtered))
(should (member t3 filtered))
(should-not (member t2 filtered))))