Skip to content

Commit 09de8cd

Browse files
committed
Merge pull request #421 from mpenet/feature/core
adds keep-indexed, map-indexed and reductions functions
2 parents 166bca7 + 1d76fc3 commit 09de8cd

2 files changed

Lines changed: 94 additions & 0 deletions

File tree

pixie/stdlib.pxi

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,6 +1727,79 @@ not enough elements were present."
17271727
(cons (take n s)
17281728
(partitionf f (drop n s)))))))
17291729

1730+
(defn map-indexed
1731+
{:doc "Returns a lazy sequence consisting of the
1732+
result of applying f to 0 and the first item of coll, followed by
1733+
applying f to 1 and the second item in coll, etc, until coll is
1734+
exhausted. Thus function f should accept 2 arguments, index and
1735+
item. Returns a stateful transducer when no collection is provided."
1736+
:added "0.1"
1737+
:signatures [[f] [f coll]]}
1738+
([f]
1739+
(fn [rf]
1740+
(let [i (atom -1)
1741+
rrf (preserving-reduced rf)]
1742+
(fn
1743+
([] (rf))
1744+
([result] (rf result))
1745+
([result input]
1746+
(rrf result (f (swap! i inc) input)))))))
1747+
([f coll]
1748+
(let [mapi (fn mapi [i coll]
1749+
(lazy-seq
1750+
(when-let [s (seq coll)]
1751+
(cons (f i (first s))
1752+
(mapi (inc i) (rest s))))))]
1753+
(mapi 0 coll))))
1754+
1755+
(defn keep-indexed
1756+
{:doc "Returns a lazy sequence of the non-nil
1757+
results of (f index item). Note, this means false return values will
1758+
be included. f must be free of side-effects. Returns a stateful
1759+
transducer when no collection is provided."
1760+
:signatures [[f] [f coll]]
1761+
:added "0.1"}
1762+
([f]
1763+
(fn [rf]
1764+
(let [iv (atom -1)
1765+
rrf (preserving-reduced rf)]
1766+
(fn
1767+
([] (rf))
1768+
([result] (rf result))
1769+
([result input]
1770+
(let [i (swap! iv inc)
1771+
v (f i input)]
1772+
(if (nil? v)
1773+
result
1774+
(rrf result v))))))))
1775+
([f coll]
1776+
(let [keepi (fn keepi [i coll]
1777+
(lazy-seq
1778+
(when-let [s (seq coll)]
1779+
(let [x (f i (first s))]
1780+
(if (nil? x)
1781+
(keepi (inc i) (rest s))
1782+
(cons x (keepi (inc i) (rest s))))))))]
1783+
(keepi 0 coll))))
1784+
1785+
(defn reductions
1786+
{:doc "Returns a lazy seq of the intermediate values of the
1787+
reduction (as per reduce) of coll by f, starting with init."
1788+
:added "0.1"
1789+
:signatures [[f coll] [f init coll]]}
1790+
([f coll]
1791+
(lazy-seq
1792+
(if-let [s (seq coll)]
1793+
(reductions f (first s) (rest s))
1794+
(list (f)))))
1795+
([f init coll]
1796+
(if (reduced? init)
1797+
(list @init)
1798+
(cons init
1799+
(lazy-seq
1800+
(when-let [s (seq coll)]
1801+
(reductions f (f init (first s)) (rest s))))))))
1802+
17301803
(defn destructure [binding expr]
17311804
(cond
17321805
(symbol? binding) [binding expr]

tests/pixie/tests/test-stdlib.pxi

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,27 @@
1919
(t/assert= (mapcat identity []) [])
2020
(t/assert= (mapcat first [[[1 2]] [[3] [:not :present]] [[4 5 6]]]) [1 2 3 4 5 6]))
2121

22+
(t/deftest test-indexed
23+
(t/assert= (map-indexed (fn [& xs] xs) []) [])
24+
(t/assert= (map-indexed (fn [& xs] xs) [:a :b]) [[0 :a] [1 :b]])
25+
(t/assert= (transduce (map-indexed (fn [& xs] xs)) conj [:a :b]) [[0 :a] [1 :b]])
26+
27+
(t/assert= (keep-indexed (constantly true) []) [])
28+
(t/assert= (keep-indexed (constantly nil) []) [])
29+
(t/assert= (keep-indexed (fn [i x] [i x]) [:a :b]) [[0 :a] [1 :b]])
30+
31+
(t/assert= (transduce (keep-indexed (constantly true)) conj []) [])
32+
(t/assert= (transduce (keep-indexed (constantly nil)) conj []) [])
33+
(t/assert= (transduce (keep-indexed (fn [i x] [i x])) conj [:a :b]) [[0 :a] [1 :b]]))
34+
35+
(t/deftest test-reductions
36+
(t/assert= (reductions + nil)
37+
[0])
38+
(t/assert= (reductions + [1 2 3 4 5])
39+
[1 3 6 10 15])
40+
(t/assert= (reductions + 10 [1 2 3 4 5])
41+
[10 11 13 16 20 25]))
42+
2243
(t/deftest test-str
2344
(t/assert= (str nil) "nil")
2445
(t/assert= (str true) "true")

0 commit comments

Comments
 (0)