(ns Enum "Elixir Enum module — eager operations on enumerables. In CljElixir: (Enum/map coll f), (Enum/reduce coll acc f), etc. Works on lists, maps, ranges, and any Enumerable.") ;; --- Mapping & Transformation --- (defn map "Returns a list with `f` applied to each element. (Enum/map [1 2 3] (fn [x] (* x 2))) ;=> [2 4 6]" [enumerable f]) (defn map-every "Applies `f` to every `nth` element, starting with the first. (Enum/map-every [1 2 3 4 5] 2 (fn [x] (* x 2))) ;=> [2 2 6 4 10]" [enumerable nth f]) (defn flat-map "Maps `f` over `enumerable` and flattens the result. (Enum/flat-map [[1 2] [3 4]] (fn [x] x)) ;=> [1 2 3 4]" [enumerable f]) (defn map-reduce "Maps and reduces in one pass. Returns {mapped_list, acc}. (Enum/map-reduce [1 2 3] 0 (fn [x acc] {(* x 2) (+ acc x)})) ;=> {[2 4 6] 6}" [enumerable acc f]) (defn scan "Returns a list of successive reduced values from the left. (Enum/scan [1 2 3 4] (fn [x acc] (+ x acc))) ;=> [1 3 6 10]" ([enumerable f]) ([enumerable acc f])) ;; --- Filtering --- (defn filter "Returns elements for which `f` returns a truthy value. (Enum/filter [1 2 3 4] (fn [x] (> x 2))) ;=> [3 4]" [enumerable f]) (defn reject "Returns elements for which `f` returns a falsy value. (Enum/reject [1 2 3 4] (fn [x] (> x 2))) ;=> [1 2]" [enumerable f]) (defn uniq "Returns unique elements, preserving order. (Enum/uniq [1 2 1 3 2]) ;=> [1 2 3]" [enumerable]) (defn uniq-by "Returns elements unique by the result of `f`. (Enum/uniq-by [{:x 1 :y 2} {:x 1 :y 3}] (fn [m] (:x m))) ;=> [{:x 1 :y 2}]" [enumerable f]) (defn dedup "Removes consecutive duplicate elements. (Enum/dedup [1 1 2 2 3 1]) ;=> [1 2 3 1]" [enumerable]) (defn dedup-by "Removes consecutive elements where `f` returns the same value." [enumerable f]) ;; --- Reducing --- (defn reduce "Invokes `f` for each element with the accumulator. (Enum/reduce [1 2 3] 0 (fn [x acc] (+ acc x))) ;=> 6 Note: Elixir callback order is (element, acc) not (acc, element)." ([enumerable f]) ([enumerable acc f])) (defn reduce-while "Reduces while `f` returns {:cont, acc}. Halts on {:halt, acc}. (Enum/reduce-while [1 2 3 4] 0 (fn [x acc] (if (< acc 5) {:cont (+ acc x)} {:halt acc})))" [enumerable acc f]) (defn map-join "Maps `f` over `enumerable` then joins results with `joiner`. (Enum/map-join [1 2 3] \", \" (fn [x] (str x))) ;=> \"1, 2, 3\"" ([enumerable f]) ([enumerable joiner f])) ;; --- Sorting --- (defn sort "Sorts the enumerable. Uses Erlang term ordering or a custom comparator. (Enum/sort [3 1 2]) ;=> [1 2 3] (Enum/sort [3 1 2] (fn [a b] (> a b))) ;=> [3 2 1]" ([enumerable]) ([enumerable sorter])) (defn sort-by "Sorts by the result of applying `mapper` to each element. (Enum/sort-by [{:name \"b\"} {:name \"a\"}] (fn [x] (:name x))) ;=> [{:name \"a\"} {:name \"b\"}]" ([enumerable mapper]) ([enumerable mapper sorter])) ;; --- Grouping & Partitioning --- (defn group-by "Groups elements by the result of `f`. (Enum/group-by [\"ant\" \"bee\" \"ape\"] (fn [s] (String/at s 0))) ;=> %{\"a\" => [\"ant\" \"ape\"], \"b\" => [\"bee\"]}" [enumerable f]) (defn chunk-by "Splits into chunks where consecutive elements return the same value for `f`. (Enum/chunk-by [1 1 2 2 3] (fn [x] x)) ;=> [[1 1] [2 2] [3]]" [enumerable f]) (defn chunk-every "Splits into chunks of `count` elements. (Enum/chunk-every [1 2 3 4 5] 2) ;=> [[1 2] [3 4] [5]]" ([enumerable count]) ([enumerable count step]) ([enumerable count step leftover])) (defn frequencies "Returns a map with keys as unique elements and values as counts. (Enum/frequencies [\"a\" \"b\" \"a\" \"c\" \"b\" \"a\"]) ;=> %{\"a\" => 3, \"b\" => 2, \"c\" => 1}" [enumerable]) (defn split-with "Splits into two lists: elements satisfying `f` and the rest. (Enum/split-with [1 2 3 4] (fn [x] (< x 3))) ;=> {[1 2] [3 4]}" [enumerable f]) (defn partition-by "Splits when `f` returns a new value. (Enum/partition-by [1 1 2 2 3] (fn [x] x)) ;=> [[1 1] [2 2] [3]]" [enumerable f]) ;; --- Lookup & Search --- (defn find "Returns the first element for which `f` returns truthy. (Enum/find [1 2 3 4] (fn [x] (> x 2))) ;=> 3" ([enumerable f]) ([enumerable default f])) (defn find-index "Returns the index of the first element for which `f` returns truthy. (Enum/find-index [1 2 3] (fn [x] (= x 2))) ;=> 1" [enumerable f]) (defn find-value "Returns the first truthy return value of `f`. (Enum/find-value [1 2 3] (fn [x] (if (> x 2) (* x 10) nil))) ;=> 30" ([enumerable f]) ([enumerable default f])) (defn member? "Returns true if `element` exists in the enumerable. (Enum/member? [1 2 3] 2) ;=> true" [enumerable element]) (defn any? "Returns true if any element satisfies `f` (or if any element is truthy). (Enum/any? [false nil true]) ;=> true (Enum/any? [1 2 3] (fn [x] (> x 2))) ;=> true" ([enumerable]) ([enumerable f])) (defn all? "Returns true if all elements satisfy `f` (or all are truthy). (Enum/all? [1 2 3] (fn [x] (> x 0))) ;=> true" ([enumerable]) ([enumerable f])) (defn count "Returns the count of elements, optionally only those satisfying `f`. (Enum/count [1 2 3]) ;=> 3 (Enum/count [1 2 3] (fn [x] (> x 1))) ;=> 2" ([enumerable]) ([enumerable f])) (defn empty? "Returns true if the enumerable is empty. (Enum/empty? []) ;=> true" [enumerable]) ;; --- Subsequences --- (defn take "Takes the first `amount` elements. (Enum/take [1 2 3 4 5] 3) ;=> [1 2 3]" [enumerable amount]) (defn take-while "Takes elements while `f` returns truthy. (Enum/take-while [1 2 3 4] (fn [x] (< x 3))) ;=> [1 2]" [enumerable f]) (defn take-every "Takes every `nth` element (0-indexed). (Enum/take-every [1 2 3 4 5 6] 2) ;=> [1 3 5]" [enumerable nth]) (defn drop "Drops the first `amount` elements. (Enum/drop [1 2 3 4 5] 2) ;=> [3 4 5]" [enumerable amount]) (defn drop-while "Drops elements while `f` returns truthy. (Enum/drop-while [1 2 3 4] (fn [x] (< x 3))) ;=> [3 4]" [enumerable f]) (defn slice "Returns a subset of the enumerable. (Enum/slice [1 2 3 4 5] 1 3) ;=> [2 3 4] (Enum/slice [1 2 3 4 5] 1..3) ;=> [2 3 4]" ([enumerable index-range]) ([enumerable start amount])) (defn reverse "Reverses the enumerable. (Enum/reverse [1 2 3]) ;=> [3 2 1]" ([enumerable]) ([enumerable tail])) (defn shuffle "Returns a list with elements in random order. (Enum/shuffle [1 2 3 4 5]) ;=> [3 1 5 2 4]" [enumerable]) ;; --- Aggregation --- (defn sum "Returns the sum of all elements. (Enum/sum [1 2 3]) ;=> 6" [enumerable]) (defn product "Returns the product of all elements. (Enum/product [1 2 3 4]) ;=> 24" [enumerable]) (defn min "Returns the minimum element. (Enum/min [3 1 2]) ;=> 1" ([enumerable]) ([enumerable empty-fallback])) (defn max "Returns the maximum element. (Enum/max [3 1 2]) ;=> 3" ([enumerable]) ([enumerable empty-fallback])) (defn min-by "Returns the element for which `f` returns the smallest value. (Enum/min-by [\"aaa\" \"b\" \"cc\"] (fn [s] (String/length s))) ;=> \"b\"" ([enumerable f]) ([enumerable f sorter])) (defn max-by "Returns the element for which `f` returns the largest value. (Enum/max-by [\"aaa\" \"b\" \"cc\"] (fn [s] (String/length s))) ;=> \"aaa\"" ([enumerable f]) ([enumerable f sorter])) (defn min-max "Returns a tuple with the minimum and maximum elements. (Enum/min-max [3 1 2]) ;=> {1 3}" ([enumerable]) ([enumerable empty-fallback])) (defn min-max-by "Returns a tuple with the min/max elements by `f`." ([enumerable f]) ([enumerable f sorter-or-empty])) ;; --- Joining & Conversion --- (defn join "Joins elements into a string with an optional separator. (Enum/join [1 2 3] \", \") ;=> \"1, 2, 3\" (Enum/join [1 2 3]) ;=> \"123\"" ([enumerable]) ([enumerable joiner])) (defn into "Inserts each element into a collectable. (Enum/into [1 2 3] []) ;=> [1 2 3] (Enum/into %{a: 1} %{b: 2}) ;=> %{a: 1, b: 2} (Enum/into [1 2 3] [] (fn [x] (* x 2))) ;=> [2 4 6]" ([enumerable collectable]) ([enumerable collectable transform])) (defn to-list "Converts an enumerable to a list. (Enum/to-list (1..5)) ;=> [1 2 3 4 5]" [enumerable]) (defn zip "Zips corresponding elements from a finite collection of enumerables. (Enum/zip [1 2 3] [:a :b :c]) ;=> [{1 :a} {2 :b} {3 :c}]" ([enumerables]) ([enum1 enum2])) (defn zip-with "Zips with a merge function. (Enum/zip-with [1 2 3] [4 5 6] (fn [a b] (+ a b))) ;=> [5 7 9]" ([enumerables zip-fun]) ([enum1 enum2 zip-fun])) (defn unzip "Opposite of zip. Takes a list of two-element tuples and returns two lists. (Enum/unzip [{1 :a} {2 :b}]) ;=> {[1 2] [:a :b]}" [list]) (defn with-index "Wraps each element in a tuple with its index. (Enum/with-index [:a :b :c]) ;=> [{:a 0} {:b 1} {:c 2}]" ([enumerable]) ([enumerable fun-or-offset])) (defn flat-map-reduce "Maps and reduces, emitting lists that get flattened. Returns {[flat_mapped], acc}." [enumerable acc f]) ;; --- Element Access --- (defn at "Returns the element at `index`. Returns `default` if out of bounds. (Enum/at [1 2 3] 1) ;=> 2 (Enum/at [1 2 3] 5 :none) ;=> :none" ([enumerable index]) ([enumerable index default])) (defn fetch "Returns {:ok element} or :error for index lookup. (Enum/fetch [1 2 3] 1) ;=> {:ok 2} (Enum/fetch [1 2 3] 5) ;=> :error" [enumerable index]) (defn fetch! "Returns the element at `index`. Raises if out of bounds. (Enum/fetch! [1 2 3] 1) ;=> 2" [enumerable index]) (defn random "Returns a random element. (Enum/random [1 2 3 4 5]) ;=> 3" ([enumerable]) ([enumerable count])) ;; --- List Operations --- (defn concat "Concatenates enumerables. (Enum/concat [1 2] [3 4]) ;=> [1 2 3 4] (Enum/concat [[1 2] [3 4]]) ;=> [1 2 3 4]" ([enumerables]) ([left right])) (defn intersperse "Inserts `separator` between each element. (Enum/intersperse [1 2 3] 0) ;=> [1 0 2 0 3]" [enumerable separator]) (defn each "Invokes `f` for each element (side effects). Returns :ok. (Enum/each [1 2 3] (fn [x] (IO/puts x)))" [enumerable f]) (defn map-intersperse "Maps and intersperses in one pass." [enumerable separator mapper]) (defn split "Splits into two lists at `count`. (Enum/split [1 2 3 4 5] 3) ;=> {[1 2 3] [4 5]}" [enumerable count])