|
1511 | 1511 | (reduce-coll val coll)
|
1512 | 1512 | (f val)))))
|
1513 | 1513 |
|
| 1514 | +(defn reduce-kv |
| 1515 | + "Reduce an associative coll by f. f must be a function of 3 |
| 1516 | + arguments: the initially supplied value (in later invocations, the |
| 1517 | + the return from previous invocations), the key of an entry of |
| 1518 | + coll, and the value of an entry of coll. |
| 1519 | + |
| 1520 | + If coll has no elements, init is returned and f is not called. |
| 1521 | + |
| 1522 | + reduce-kv may reduce vectors in addition to maps. Vectors have |
| 1523 | + non-negative integer keys." |
| 1524 | + [f init coll] |
| 1525 | + (if (seq coll) |
| 1526 | + (loop [in-coll coll |
| 1527 | + assoc-coll init] |
| 1528 | + (let [entry (first in-coll) |
| 1529 | + k (key entry) |
| 1530 | + v (val entry) |
| 1531 | + rem (rest in-coll)] |
| 1532 | + (if (seq rem) |
| 1533 | + (recur rem (f assoc-coll k v)) |
| 1534 | + (f assoc-coll k v)))) |
| 1535 | + init)) |
| 1536 | + |
1514 | 1537 | (defn comp
|
1515 | 1538 | "Return a function which is the composition of all the functions
|
1516 | 1539 | given as arguments. Note that, as in mathematical function composition,
|
|
1550 | 1573 | (pred (first coll)) (recur pred (rest coll))
|
1551 | 1574 | :else false))
|
1552 | 1575 |
|
| 1576 | +(defn every-pred |
| 1577 | + "Return a predicate composed of all of the input predicates, which returns |
| 1578 | + true if all input predicates return true for a value, otherwise returns false. |
| 1579 | + The returned predicate returns false on the first failing predicate and will |
| 1580 | + not execute any remaining predicates." |
| 1581 | + ([pred] |
| 1582 | + (fn [& args] |
| 1583 | + (every? pred args))) |
| 1584 | + ([pred & preds] |
| 1585 | + (let [comp-pred (reduce (fn [f g] |
| 1586 | + (fn [v] |
| 1587 | + (if (and (f v) (g v)) |
| 1588 | + true |
| 1589 | + false))) |
| 1590 | + pred |
| 1591 | + preds)] |
| 1592 | + (fn [& args] |
| 1593 | + (every? comp-pred args))))) |
| 1594 | + |
1553 | 1595 | (def
|
1554 | 1596 | ^{:doc "Return true if not every element in coll satisfies pred."}
|
1555 | 1597 | not-every?
|
|
1562 | 1604 | (or (pred (first coll))
|
1563 | 1605 | (recur pred (rest coll)))))
|
1564 | 1606 |
|
| 1607 | +(defn some-fn |
| 1608 | + "Return a predicate composed of all of the input functions, which returns |
| 1609 | + the first truthy return value from one of the inputs, otherwise returns nil. |
| 1610 | + The returned predicate returns the first truthy value it encounters and will |
| 1611 | + not execute any remaining functions." |
| 1612 | + ([f] |
| 1613 | + (fn [& args] |
| 1614 | + (some f args))) |
| 1615 | + ([f & fs] |
| 1616 | + (let [comp-f (reduce (fn [f g] |
| 1617 | + (fn [v] |
| 1618 | + (or (f v) (g v)))) |
| 1619 | + f |
| 1620 | + fs)] |
| 1621 | + (fn [& args] |
| 1622 | + (some comp-f args))))) |
| 1623 | + |
1565 | 1624 | (def
|
1566 | 1625 | ^{:doc "Return true if no element in coll satisfies pred."}
|
1567 | 1626 | not-any?
|
1568 | 1627 | (comp not some))
|
1569 | 1628 |
|
1570 | 1629 | (defn map
|
1571 |
| - "Return a lazy sequence of (f elem) for elements in coll." |
| 1630 | + "Return a lazy sequence of (f elem) for elements in coll. More than one |
| 1631 | + collection may be supplied. If more than one collection is supplied, the |
| 1632 | + function f will be passed sequential elements from each collection on each |
| 1633 | + invocation and must be able to accept as many arguments as there are |
| 1634 | + collections. The sequence will terminate when at least one input collection |
| 1635 | + is exhausted." |
1572 | 1636 | ([f coll]
|
1573 | 1637 | (lazy-seq
|
1574 | 1638 | (when (seq coll)
|
|
1579 | 1643 | (cons (apply f (first coll) (map first colls))
|
1580 | 1644 | (apply map f (rest coll) (map rest colls)))))))
|
1581 | 1645 |
|
| 1646 | +(def ^{:doc "Return a vector of (f elem) for elements in coll. More than one |
| 1647 | + collection may be supplied. If more than one collection is supplied, the |
| 1648 | + function f will be passed sequential elements from each collection on each |
| 1649 | + invocation and must be able to accept as many arguments as there are |
| 1650 | + collections. The sequence will terminate when at least one input collection |
| 1651 | + is exhausted."} |
| 1652 | + mapv (comp vec map)) |
| 1653 | + |
1582 | 1654 | (defn map-indexed
|
1583 | 1655 | "Return a lazy sequence of (f idx elem) for elements in coll. The
|
1584 | 1656 | index starts at 0."
|
|
1592 | 1664 | (apply concat (apply map f colls)))
|
1593 | 1665 |
|
1594 | 1666 | (defn filter
|
1595 |
| - "Return elements from coll where (pred elem) returns true." |
| 1667 | + "Return a lazy sequence of elements from coll where (pred elem) returns true." |
1596 | 1668 | [pred coll]
|
1597 | 1669 | (lazy-seq
|
1598 | 1670 | (when (seq coll)
|
1599 | 1671 | (if (pred (first coll))
|
1600 | 1672 | (cons (first coll) (filter pred (rest coll)))
|
1601 | 1673 | (filter pred (rest coll))))))
|
1602 | 1674 |
|
| 1675 | +(def ^{:doc "Return a lazy sequence of elements from coll where (pred elem) |
| 1676 | + returns true."} |
| 1677 | + filterv (comp vec filter)) |
| 1678 | + |
1603 | 1679 | (defn remove
|
1604 | 1680 | "Return elements from coll where (pred elem) returns false."
|
1605 | 1681 | [pred coll]
|
|
1609 | 1685 | (cons (first coll) (remove pred (rest coll)))
|
1610 | 1686 | (remove pred (rest coll))))))
|
1611 | 1687 |
|
| 1688 | +(defn keep |
| 1689 | + "Return a lazy sequence of non-nil results of (f elem) for elements in coll." |
| 1690 | + [f coll] |
| 1691 | + (lazy-seq |
| 1692 | + (when (seq coll) |
| 1693 | + (let [elem (first coll)] |
| 1694 | + (if-not (nil? (f elem)) |
| 1695 | + (cons elem (keep f (rest coll))) |
| 1696 | + (keep f (rest coll))))))) |
| 1697 | + |
| 1698 | +(defn keep-indexed |
| 1699 | + "Return a lazy-sequence of non-nil results of (f index elem) for elements |
| 1700 | + in coll." |
| 1701 | + [f coll] |
| 1702 | + (let [keep-idx (fn keep-idx |
| 1703 | + [rng coll] |
| 1704 | + (lazy-seq |
| 1705 | + (when (seq coll) |
| 1706 | + (let [idx (first rng) |
| 1707 | + elem (first coll)] |
| 1708 | + (if-not (nil? (f idx elem)) |
| 1709 | + (cons elem (keep-idx (rest rng) (rest coll))) |
| 1710 | + (keep-idx (rest rng) (rest coll)))))))] |
| 1711 | + (keep-idx (range) coll))) |
| 1712 | + |
1612 | 1713 | (defn take
|
1613 | 1714 | "Return the first n elements of coll."
|
1614 | 1715 | [n coll]
|
|
1688 | 1789 | (cons sep (interpose sep (rest coll))))
|
1689 | 1790 | (cons (first coll) nil)))))
|
1690 | 1791 |
|
| 1792 | +(defn interleave |
| 1793 | + "Return a lazy sequence consisting of the first element of coll, then the |
| 1794 | + first element of the following coll, etc. until the shortest input collection |
| 1795 | + is exhausted." |
| 1796 | + ([] '()) |
| 1797 | + ([coll] (seq coll)) |
| 1798 | + ([coll & colls] |
| 1799 | + (let [coll-firsts (fn coll-firsts |
| 1800 | + [& colls] |
| 1801 | + (lazy-seq |
| 1802 | + (when (seq colls) |
| 1803 | + (cons (ffirst colls) (apply coll-firsts (rest colls))))))] |
| 1804 | + (lazy-seq |
| 1805 | + (when (and (seq coll) (every? seq colls)) |
| 1806 | + (concat (apply coll-firsts coll colls) |
| 1807 | + (apply interleave (rest coll) (map rest colls)))))))) |
| 1808 | + |
1691 | 1809 | (defn cycle
|
1692 | 1810 | "Cycle the items in coll infinitely."
|
1693 | 1811 | [coll]
|
|
1734 | 1852 | of step elements. If step is not given, steps of size n will be used
|
1735 | 1853 | and there will be no overlap between partitions. If pad is given,
|
1736 | 1854 | partition will pull elements from pad until the final sequence is
|
1737 |
| - equal to size n." |
| 1855 | + equal to size n. If there are fewer than n leftover elements in coll, |
| 1856 | + they will not be returned as a partial partition." |
1738 | 1857 | ([n coll]
|
1739 | 1858 | (partition n n coll))
|
1740 | 1859 | ([n step coll]
|
1741 | 1860 | (lazy-seq
|
1742 | 1861 | (when (seq coll)
|
1743 |
| - (cons (take n coll) (partition n step (drop step coll)))))) |
| 1862 | + (let [s (take n coll)] |
| 1863 | + (when (= n (count s)) |
| 1864 | + (cons s (partition n step (drop step coll)))))))) |
1744 | 1865 | ([n step pad coll]
|
1745 | 1866 | (lazy-seq
|
1746 | 1867 | (when (seq coll)
|
|
1751 | 1872 | s)]
|
1752 | 1873 | (cons s (partition n step pad (drop step coll))))))))
|
1753 | 1874 |
|
| 1875 | +(defn partition-all |
| 1876 | + "Return a lazy sequence of partitions of coll of size n at offsets |
| 1877 | + of step elements. If step is not given, steps of size n will be used |
| 1878 | + and there will be no overlap between partitions. If there are leftover |
| 1879 | + elements from coll which do not fill a full partition, then a partial |
| 1880 | + partition will be returned, unlike partition." |
| 1881 | + ([n coll] |
| 1882 | + (partition-all n n coll)) |
| 1883 | + ([n step coll] |
| 1884 | + (lazy-seq |
| 1885 | + (when (seq coll) |
| 1886 | + (cons (take n coll) (partition-all n step (drop step coll))))))) |
| 1887 | + |
1754 | 1888 | (defn partition-by
|
1755 | 1889 | "Return a lazy sequence of partitions, splitting coll each time f
|
1756 | 1890 | returns a different value."
|
|
1762 | 1896 | run (cons elem (take-while #(= felem (f %)) (next coll)))]
|
1763 | 1897 | (cons run (partition-by f (seq (drop (count run) coll))))))))
|
1764 | 1898 |
|
| 1899 | +(defn min-key |
| 1900 | + "Return the arg for which (k arg) is the smallest number. |
| 1901 | + If multiple values return the same number, return the last." |
| 1902 | + [k & args] |
| 1903 | + (reduce (fn [cur nxt] |
| 1904 | + (if (<= (k nxt) (k cur)) |
| 1905 | + nxt |
| 1906 | + cur)) |
| 1907 | + (first args) |
| 1908 | + (rest args))) |
| 1909 | + |
| 1910 | +(defn max-key |
| 1911 | + "Return the arg for which (k arg) is the largest number. |
| 1912 | + If multiple values return the same number, return the last." |
| 1913 | + [k & args] |
| 1914 | + (reduce (fn [cur nxt] |
| 1915 | + (if (>= (k nxt) (k cur)) |
| 1916 | + nxt |
| 1917 | + cur)) |
| 1918 | + (first args) |
| 1919 | + (rest args))) |
| 1920 | + |
| 1921 | +(defn sort-by |
| 1922 | + "Return a sorted sequence of the elements from coll." |
| 1923 | + ([keyfn coll] |
| 1924 | + (basilisp.lang.runtime/sort-by keyfn coll)) |
| 1925 | + ([keyfn cmp coll] |
| 1926 | + (basilisp.lang.runtime/sort-by keyfn coll cmp))) |
| 1927 | + |
1765 | 1928 | (defn merge
|
1766 | 1929 | "Merge maps together from left to right as by conj. If a duplicate key
|
1767 | 1930 | appears in a map, the rightmost map's value for that key will be taken."
|
|
1771 | 1934 | {}
|
1772 | 1935 | maps)))
|
1773 | 1936 |
|
| 1937 | +(defn trampoline |
| 1938 | + "Trampoline f with starting arguments. If f returns an fn, call its return |
| 1939 | + value with no arguments, repeating that process until the return value is not |
| 1940 | + a fn." |
| 1941 | + [f & args] |
| 1942 | + (loop [ret (apply f args)] |
| 1943 | + (if (fn? ret) |
| 1944 | + (recur (ret)) |
| 1945 | + ret))) |
| 1946 | + |
1774 | 1947 | ;;;;;;;;;;;;;;;;;;;;;;
|
1775 | 1948 | ;; Random Functions ;;
|
1776 | 1949 | ;;;;;;;;;;;;;;;;;;;;;;
|
|
3012 | 3185 | ;; Associative Functions ;;
|
3013 | 3186 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
3014 | 3187 |
|
| 3188 | +(defn replace |
| 3189 | + "Replace elements of the vector/seq coll with matching elements from the |
| 3190 | + associative collection smap, if they exist." |
| 3191 | + [smap coll] |
| 3192 | + (if (vector? coll) |
| 3193 | + (reduce (fn [res v] |
| 3194 | + (if-let [newv (get smap v)] |
| 3195 | + (conj res newv) |
| 3196 | + res)) |
| 3197 | + [] |
| 3198 | + coll) |
| 3199 | + (map (fn [v] |
| 3200 | + (if-let [newv (get smap v)] |
| 3201 | + newv |
| 3202 | + v)) |
| 3203 | + coll))) |
| 3204 | + |
3015 | 3205 | (defn select-keys
|
3016 | 3206 | "Return a map with only the keys of m which are in ks."
|
3017 | 3207 | [m ks]
|
|
0 commit comments