### Game of Life Blinker Simulation Source: https://github.com/cgrand/xforms/wiki/Conway's-game-of-life,-transducers-edition This example demonstrates simulating a 'blinker' pattern in the Game of Life using the 'step' function. It initializes a board with the blinker pattern and then iterates the 'step' function 5 times to show its evolution. The output displays the set of live cells at each generation. ```clojure => (def board #{[1 0] [1 1] [1 2]}) ; blinker => (take 5 (iterate step board)) (#{[1 0] [1 1] [1 2]} #{[1 1] [2 1] [0 1]} #{[1 0] [1 1] [1 2]} #{[1 1] [2 1] [0 1]} #{[1 0] [1 1] [1 2]}) ``` -------------------------------- ### Require xforms Library Source: https://github.com/cgrand/xforms/wiki/Conway's-game-of-life,-transducers-edition This snippet demonstrates how to import the xforms library into a Clojure project using the 'require' function. It makes the library's functions available under the 'x' alias. ```clojure (require '[net.cgrand.xforms :as x]) ``` -------------------------------- ### Using xforms Dependency in Clojure Source: https://github.com/cgrand/xforms/blob/master/README.md Demonstrates how to require the xforms library in a Clojure project for use in your code. This is the initial setup step for utilizing any xforms functionality. ```clojure => (require '[net.cgrand.xforms :as x]) ``` -------------------------------- ### Configure Cider Middleware for Figwheel REPL (Clojurescript) Source: https://github.com/cgrand/xforms/blob/master/README.md This configuration snippet shows how to correctly include `cider.nrepl/cider-middleware` in your Clojurescript figwheel project. Proper middleware setup prevents unexpected behavior where REPL results are returned as strings. ```clojurescript :figwheel { ... :nrepl-middleware [cider.nrepl/cider-middleware;;<= that middleware refactor-nrepl.middleware/wrap-refactor cemerick.piggieback/wrap-cljs-repl] ...} ``` -------------------------------- ### Clojure: x/by-key with map transformation Source: https://github.com/cgrand/xforms/wiki/Introduction Illustrates `x/by-key` used as a transducer to apply a transformation (e.g., `map inc`) to values associated with each key. The example shows how `x/by-key` establishes a sub-context for each key. ```clojure => (into {} (x/by-key (map inc)) {:a 1 :b 2 :c 3 :d 4}) {:a 2, :b 3, :c 4, :d 5} ``` -------------------------------- ### Windowed Accumulations with xforms window Source: https://github.com/cgrand/xforms/blob/master/README.md Explains and demonstrates the `xforms/window` transducer for calculating rolling accumulators over a sliding window. Examples include summing the last 3 items, calculating the average of the last 4 items, and finding the minimum within a window using a custom reducing function. ```clojure ;; sum of last 3 items => (sequence (x/window 3 + -) (range 16)) (0 1 3 6 9 12 15 18 21 24 27 30 33 36 39 42) => (def nums (repeatedly 8 #(rand-int 42))) #'user/nums => nums (11 8 32 26 6 10 37 24) ;; avg of last 4 items => (sequence (x/window 4 rf/avg #(rf/avg %1 %2 -1)) nums) (11 19/2 17 77/4 18 37/2 79/4 77/4) ;; min of last 3 items => (sequence (x/window 3 (fn ([] (sorted-map)) ([m] (key (first m))) ([m x] (update m x (fnil inc 0)))) (fn [m x] (let [n (dec (m x))] (if (zero? n) (dissoc m x) (assoc m x (dec n)))))) nums) (11 8 8 8 6 6 6 10) ``` -------------------------------- ### Multi-pass Transductions with xforms transjuxt Source: https://github.com/cgrand/xforms/blob/master/README.md Demonstrates using `xforms/transjuxt` to perform multiple transductions simultaneously on a collection. Examples include calculating sum and average using `x/reduce +` and `x/avg`, and using named results with a map. ```clojure => (into {} (x/by-key odd? (x/transjuxt [(x/reduce +) x/avg])) (range 256)) {false [16256 127], true [16384 128]} => (into {} (x/by-key odd? (x/transjuxt {:sum (x/reduce +) :mean x/avg :count x/count})) (range 256)) {false {:sum 16256, :mean 127, :count 128}, true {:sum 16384, :mean 128, :count 128}} ``` -------------------------------- ### Game of Life Step Function (Reduced Approach) Source: https://github.com/cgrand/xforms/wiki/Conway's-game-of-life,-transducers-edition An alternative implementation of the Game of Life 'step' function using xforms. This version first maps each potential cell to its neighbor count and then uses x/reduce to sum counts by cell key. Finally, it filters cells based on Game of Life rules. ```clojure (defn step [cells] (x/into #{} (comp (x/for [[x y] % dx [-1 0 1] dy (if (zero? dx) [-1 1] [-1 0 1])] [[(+ dx x) (+ dy y)] 1]) (x/by-key (x/reduce +)) (x/for [[cell n] % :when (or (= n 3) (and (= n 2) (cells cell)))] cell)) cells)) ``` -------------------------------- ### Group by key, extract value, and customize recombination Source: https://github.com/cgrand/xforms/wiki/Introduction This snippet showcases the 4-arity version of x/by-key, allowing control over key extraction, value extraction, and a custom recombination function. The example groups by `:continent`, extracts `:country` as the value, and then recombines them into a new map structure with `:continent` and `:countries` keys. ```clojure => (into [] (x/by-key :continent :country (fn [continent countries] {:continent continent :countries countries}) (x/into [])) [{:country "USA" :continent "North America"} {:country "Canada" :continent "North America"} {:country "France" :continent "Europe"} {:country "Germany" :continent "Europe"}]) [{:continent "North America", :countries ["USA" "Canada"]} {:continent "Europe", :countries ["France" "Germany"]}] ``` -------------------------------- ### Game of Life Step Function (Iterative Approach) Source: https://github.com/cgrand/xforms/wiki/Conway's-game-of-life,-transducers-edition This Clojure code defines a 'step' function for the Game of Life. It calculates the next state of a cellular automaton based on the current state of cells. It uses xforms for efficient iteration and transformation, including calculating neighbors and applying Game of Life rules. ```clojure (defn step [cells] "Calculates the next state of the Game of Life." (into #{} (comp (x/for [[x y] % dx [-1 0 1] dy (if (zero? dx) [-1 1] [-1 0 1])] [(+ dx x) (+ dy y)]) (x/by-key identity x/count) (x/for [[cell n] % :when (or (= n 3) (and (= n 2) (cells cell)))] cell)) cells)) ``` -------------------------------- ### Partitioning and Grouping with Xforms Source: https://github.com/cgrand/xforms/blob/master/README.md Demonstrates the use of `x/partition` and `x/by-key` transducers for data partitioning and grouping. Shows how to process each partition further and aggregate results using `x/into`. ```clojure => (sequence (x/partition 2 1 identity) (range 8)) (0 1 1 2 2 3 3 4 4 5 5 6 6 7) ``` ```clojure => (sequence (x/by-key odd? identity) (range 8)) ([false 0] [true 1] [false 2] [true 3] [false 4] [true 5] [false 6] [true 7]) ``` ```clojure => (sequence (x/partition 2 1 (x/into [])) (range 8)) ([0 1] [1 2] [2 3] [3 4] [4 5] [5 6] [6 7]) ``` ```clojure => (sequence (x/by-key odd? (x/into [])) (range 8)) ([false [0 2 4 6]] [true [1 3 5 7]]) ``` -------------------------------- ### Partitioning Collections with xforms partition Source: https://github.com/cgrand/xforms/blob/master/README.md Shows how to use `xforms/partition` to divide a collection into sub-collections of a specified size. It demonstrates basic partitioning and how to use a transducer like `x/reduce +` or `x/into []` for processing partitions, including padding. ```clojure => (sequence (x/partition 4 (x/reduce +)) (range 16)) (6 22 38 54) => (sequence (x/partition 4 4 (repeat :pad) (x/into [])) (range 9)) ([0 1 2 3] [4 5 6 7] [8 :pad :pad :pad]) ``` -------------------------------- ### Efficient Looping with xforms for Source: https://github.com/cgrand/xforms/blob/master/README.md Illustrates the use of `xforms/for` as a more performant alternative to `clojure.core/for` when used with `transduce`. It shows how `x/for` can be expanded into `eduction` for similar functionality. ```clojure => (quick-bench (reduce + (for [i (range 128) j (range i)] (* i j)))) Execution time mean : 514,932029 µs => (quick-bench (transduce (x/for [i % j (range i)] (* i j)) + 0 (range 128))) Execution time mean : 373,814060 µs You can also use `for` like `clojure.core/for`: `(x/for [i (range 128) j (range i)] (* i j))` expands to `(eduction (x/for [i % j (range i)] (* i j)) (range 128))`. ``` -------------------------------- ### Clojure: Using x/into with collection building Source: https://github.com/cgrand/xforms/wiki/Introduction Demonstrates the 1-argument arity of `x/into`, which returns a transducer that builds a collection by adding items. The final collection is returned when the transducing context is done. This differs from the standard `into` by allowing a transducer to be directly provided. ```clojure => (into [:core-into-vector] (x/into [:x-into-vector]) (range 10)) [:core-into-vector [:x-into-vector 0 1 2 3 4 5 6 7 8 9]] ``` -------------------------------- ### Xforms Shorthands for Common Operations Source: https://github.com/cgrand/xforms/blob/master/README.md Illustrates how Xforms provides convenient shorthands for common data manipulation tasks by composing existing transducers. ```clojure (group-by kf coll) is (into {} (x/by-key kf (x/into []) coll)) ``` ```clojure (plumbing/map-vals f m) is (into {} (x/by-key (map f)) m) ``` ```clojure (reduce-by kf f init coll) is (into {} (x/by-key kf (x/reduce f init))) ``` ```clojure (frequencies coll) is (into {} (x/by-key identity x/count) coll) ``` -------------------------------- ### Optimizing Key-Value Pair Processing with Xforms Source: https://github.com/cgrand/xforms/blob/master/README.md Compares the performance of standard Clojure `for` with Xforms' `x/for` and `x/into` for processing key-value pairs, demonstrating significant speed improvements by avoiding intermediate allocations. ```clojure ;; plain old sequences => (let [m (zipmap (range 1e5) (range 1e5))] (crit/quick-bench (into {} (for [[k v] m] [k (inc v)])))) Evaluation count : 12 in 6 samples of 2 calls. Execution time mean : 55,150081 ms Execution time std-deviation : 1,397185 ms ``` ```clojure ;; x/for but pairs are allocated (because of into) => (let [m (zipmap (range 1e5) (range 1e5))] (crit/quick-bench (into {} (x/for [[k v] _] [k (inc v)]) m))) Evaluation count : 18 in 6 samples of 3 calls. Execution time mean : 39,119387 ms Execution time std-deviation : 1,456902 ms ``` ```clojure ;; x/for but no pairs are allocated (thanks to x/into) => (let [m (zipmap (range 1e5) (range 1e5))] (crit/quick-bench (x/into {} (x/for [[k v] %] [k (inc v)]) m))) Evaluation count : 24 in 6 samples of 4 calls. Execution time mean : 24,276790 ms Execution time std-deviation : 364,932996 µs ``` -------------------------------- ### Grouping Collections with xforms by-key and reduce/into Source: https://github.com/cgrand/xforms/blob/master/README.md Demonstrates reimplementing `group-by` using `x/by-key` with either `x/reduce conj` or `x/into []` for efficient grouping. It includes a performance comparison against the core `group-by` function. ```clojure (defn my-group-by [kfn coll] (into {} (x/by-key kfn (x/reduce conj)) coll)) ;; let's go transient! (defn my-group-by [kfn coll] (into {} (x/by-key kfn (x/into [])) coll)) => (quick-bench (group-by odd? (range 256))) Execution time mean : 29,356531 µs => (quick-bench (my-group-by odd? (range 256))) Execution time mean : 20,604297 µs ``` -------------------------------- ### Timing Transducer Execution with Xforms Source: https://github.com/cgrand/xforms/blob/master/README.md Demonstrates how to use the `x/time` transducer to measure the execution time of specific parts of a transformation pipeline, excluding time spent in downstream operations. ```clojure => (time ; good old Clojure time (count (into [] (comp (x/time "mapinc" (map inc)) (x/time "filterodd" (filter odd?))) (range 1e6)))) filterodd: 61.771738 msecs mapinc: 143.895317 msecs "Elapsed time: 438.34291 msecs" 500000 ``` -------------------------------- ### Clojure: x/by-key with summation using reduce Source: https://github.com/cgrand/xforms/wiki/Introduction Demonstrates `x/by-key` used with `x/reduce` to perform an aggregation (like summation) on values for each key. The composition is done using `comp`, enabling per-key reduction. ```clojure => (into {} (x/by-key (x/reduce +)) (concat {:a 1 :b 2} {:a 3 :b 4})) {:a 4, :b 6} ``` -------------------------------- ### Clojure: x/by-key with collection output using into Source: https://github.com/cgrand/xforms/wiki/Introduction Illustrates `x/by-key` combined with `x/into` to collect multiple transformed values for each key into a collection. This is achieved by composing the transducers using `comp`. ```clojure => (into [] (x/by-key (mapcat (fn [v] [v (- v)]))) {:a 1 :b 2 :c 3 :d 4}) [[:a 1] [:a -1] [:b 2] [:b -2] [:c 3] [:c -3] [:d 4] [:d -4]] ``` ```clojure => (into [] (x/by-key (map inc)) (concat {:a 1 :b 2} {:a 3 :b 4})) [[:a 2] [:b 3] [:a 4] [:b 5]] ``` ```clojure => (into {} (x/by-key (x/into [])) (concat {:a 1 :b 2} {:a 3 :b 4})) {:a [1 3], :b [2 4]} ``` -------------------------------- ### Clojure: Composing transducers with x/by-key Source: https://github.com/cgrand/xforms/wiki/Introduction Explains the correct way to compose transducers with `x/by-key`, emphasizing the use of `comp` for combining transformations like `map inc` with `x/into` or `x/reduce`. This avoids issues with non-transducer-aware functions. ```clojure => (comp (map inc) (x/into [])) #object[clojure.core.async.impl.protocols.transducer "..."] ``` ```clojure => (comp (map inc) (x/reduce +)) #object[clojure.core.async.impl.protocols.transducer "..."] ``` -------------------------------- ### Clojure: Using x/reduce for transducer reduction Source: https://github.com/cgrand/xforms/wiki/Introduction Shows how `x/reduce` performs a reduction operation within a transducing context. It follows the `transduce` behavior for its reducing function (`rf`), calling `(rf)` when no initial value is provided and `(rf acc)` upon completion. ```clojure => (into [] (x/reduce +) (range 10)) [45] ``` -------------------------------- ### String Concatenation with xforms str Source: https://github.com/cgrand/xforms/blob/master/README.md Compares the performance of `clojure.core/reduce str` with `net.cgrand.xforms/str` for string concatenation. `x/str` is shown to be more efficient for building strings linearly. ```clojure => (quick-bench (reduce str (range 256))) Execution time mean : 58,714946 µs => (quick-bench (reduce rf/str (range 256))) Execution time mean : 11,609631 µs ``` -------------------------------- ### Group by key and collect values (group-by reimplementation) Source: https://github.com/cgrand/xforms/wiki/Introduction This snippet shows how to use x/by-key with a key function to group items and collect the entire item as the value, effectively reimplementing Clojure's `group-by` function. It demonstrates grouping by `:continent` and collecting all associated map entries. Uses `x/into` for efficient collection. ```clojure => (into {} (x/by-key :continent (x/into [])) [{:country "USA" :continent "North America"} {:country "Canada" :continent "North America"} {:country "France" :continent "Europe"} {:country "Germany" :continent "Europe"}]) {"North America" [{:country "USA", :continent "North America"} {:country "Canada", :continent "North America"}], "Europe" [{:country "France", :continent "Europe"} {:country "Germany", :continent "Europe"}]} ``` -------------------------------- ### Clojure: x/by-key with conditional filtering Source: https://github.com/cgrand/xforms/wiki/Introduction Demonstrates `x/by-key` filtering values based on a condition (e.g., `filter odd?`). Keys whose transformed values do not meet the criteria are omitted from the final result, showcasing context termination. ```clojure => (into {} (x/by-key (filter odd?)) {:a 1 :b 2 :c 3 :d 4}) {:a 1, :c 3} ``` -------------------------------- ### Clojure: x/by-key with multiple values per key Source: https://github.com/cgrand/xforms/wiki/Introduction Shows `x/by-key` handling transformations that emit multiple values for a single key (e.g., `mapcat`). The behavior regarding multiple values depends on the final aggregation method, such as `into {}` which typically keeps the last value. ```clojure => (into {} (x/by-key (mapcat (fn [v] [v (- v)]))) {:a 1 :b 2 :c 3 :d 4}) {:a -1, :b -2, :c -3, :d -4} ``` -------------------------------- ### Group by key and extract specific value Source: https://github.com/cgrand/xforms/wiki/Introduction This snippet demonstrates using x/by-key with both a key function (`:continent`) and a value function (`:country`). This allows grouping by a specific key while extracting a different specific field as the value for each group. It's useful for transforming grouped data without retaining intermediate structures. ```clojure => (into {} (x/by-key :continent :country (x/into [])) [{:country "USA" :continent "North America"} {:country "Canada" :continent "North America"} {:country "France" :continent "Europe"} {:country "Germany" :continent "Europe"}]) {"North America" ["USA" "Canada"], "Europe" ["France" "Germany"]} ``` -------------------------------- ### Efficiently map values of a map using xforms Source: https://github.com/cgrand/xforms/wiki/Introduction This Clojure code defines a `map-vals` function that efficiently applies a transformation function `f` to the values of a map `m`. It leverages `x/into` and `x/by-key` to achieve this, likely optimizing for performance by using transients and avoiding unnecessary allocations. ```clojure (defn map-vals [m f] (x/into m (x/by-key (map f)) m)) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.