Login
7 branches 0 tags
Ben (X13/Arch) Simplified things a little 0643405 9 days ago 1260 Commits
nujel / stdlib / collections / collection.nuj
;;; Nujel - Copyright (C) 2020-2021 - Benjamin Vincent Schulenburg
;;; This project uses the MIT license, a copy should be included under /LICENSE
;;;
;;; A bunch of procedurs that work on all collections where the collection primitives are implemented

(defn sum (collection)
      "Return the sum of every value in collection"
      :cat :collection-operations

      (reduce collection + 0))

(defn every? (collection predicate?)
      "Returns whether predicate? is #t for every member of the collection"
      :cat :collection-operations

      (reduce collection (fn (a b) (and a (predicate? b))) #t))

(defn count (collection predicate?)
      "Count the number of items in the collection where predicate? is #t.
      If no predicate is provided, it will count the number of elements instead."
      :cat :collection-operations

      (if predicate?
          (reduce collection (fn (a b) (+ a (if (predicate? b) 1 0))) 0)
          (reduce collection (fn (a b) (+ a 1)) 0)))

(defn delete (l e)
      "Returns a filtered list l with all elements equal to e omitted"
      (filter l (fn (a) (not (= a e)))))

(defn remove (l p)
      "Returns a filtered list l with all elements where P equal true removed"
      (filter l (fn (a) (not (p a)))))

(def flatten (let*
               (defn flatten-λ (a b)
                     (cond ((collection? b ) (append (reduce b flatten-λ #nil) a))
                           (#t (cons b a))))
               (defn flatten (l)
                     "Flatten a collection of collections into a simple list"
                     (if-not (collection? l) l
                             (nreverse (reduce l flatten-λ #nil))))))

(defn join (l glue)
      "Join every element of α together into a string with GLUE inbetween"
      (when-not glue (set! glue ""))
      (when-not l (return ""))
      (reduce l (fn (a b) (if a (cat a glue b) b)) #nil))

(defn for-each (l f)
      "Runs F over every item in collection L"
      (def ret #nil)
      (doseq (i l ret)
             (set! ret (f i))))