Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add window function #98

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open

Add window function #98

wants to merge 2 commits into from

Conversation

tomdl89
Copy link
Contributor

@tomdl89 tomdl89 commented Mar 5, 2025

I've had the lazy-only version of this function in quite a few codebases over the years, and recently took the time to write the transducer version. The cljs support is particularly annoying to write because cljs's array-list type doesn't implement a remove method.

This is like a simple alternative to https://github.com/cgrand/xforms/ 's window transducer, which needs f and invf functions to construct the windows. Plus this has a standard lazy-arity.

An example use case:

(def months [{:month "Jan" :income 500}
             {:month "Feb" :income 450}
             {:month "Mar" :income 580}
             {:month "Apr" :income 420}
             {:month "May" :income 680}])

(->> (window 3 months)
     (map (fn [months]
            {:month (:month (last months))
             :last-3-avg (/ (reduce (fn [acc x] (+ (:income x) acc)) 0 months)
                            (count months))})))
;; => ({:month "Jan", :last-3-avg 500}
;;     {:month "Feb", :last-3-avg 475}
;;     {:month "Mar", :last-3-avg 510}
;;     {:month "Apr", :last-3-avg 483}
;;     {:month "May", :last-3-avg 560})

Copy link
Owner

@weavejester weavejester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. My initial impression is that this is reasonable, but let me give it a some thought first.

when no collection is provided. For a sliding window containing each element
and n-1 _following_ elements, use `clojure.core/partition` with a `step` size
of 1."
{:added "1.10.0"}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be 1.9.0 I believe.

(letfn [(part [part-n coll]
(let [run (doall (take part-n coll))]
(lazy-seq
(when (== part-n (count run))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is using == over = due to performance reasons? What do the benchmarks come out with when comparing the two?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants