diff --git a/src/boot/boot.janet b/src/boot/boot.janet index 93a2a393..88598f66 100644 --- a/src/boot/boot.janet +++ b/src/boot/boot.janet @@ -643,7 +643,12 @@ (defn mean "Returns the mean of xs. If empty, returns NaN." [xs] - (/ (sum xs) (length xs))) + (if (lengthable? xs) + (/ (sum xs) (length xs)) + (do + (var [accum total] [0 0]) + (each x xs (+= accum x) (++ total)) + (/ accum total)))) (defn product "Returns the product of xs. If xs is empty, returns 1." @@ -1730,20 +1735,28 @@ ret)) @[])) +(defn- partition-slice + [f n ind] + (var [start end] [0 n]) + (def len (length ind)) + (def parts (div len n)) + (def ret (array/new-filled parts)) + (forv k 0 parts + (put ret k (f ind start end)) + (set start end) + (+= end n)) + (if (< start len) + (array/push ret (f ind start))) + ret) + (defn partition ``Partition an indexed data structure `ind` into tuples of size `n`. Returns a new array.`` [n ind] - (var i 0) (var nextn n) - (def len (length ind)) - (def ret (array/new (math/ceil (/ len n)))) - (def slicer (if (bytes? ind) string/slice tuple/slice)) - (while (<= nextn len) - (array/push ret (slicer ind i nextn)) - (set i nextn) - (+= nextn n)) - (if (not= i len) (array/push ret (slicer ind i))) - ret) + (cond + (indexed? ind) (partition-slice tuple/slice n ind) + (bytes? ind) (partition-slice string/slice n ind) + (partition-slice tuple/slice n (values ind)))) ### ### diff --git a/test/suite-boot.janet b/test/suite-boot.janet index 49f5ee03..61bc6c6b 100644 --- a/test/suite-boot.janet +++ b/test/suite-boot.janet @@ -349,6 +349,13 @@ "sort 5") (assert (<= ;(sort (map (fn [x] (math/random)) (range 1000)))) "sort 6") +# #1283 +(assert (deep= + (partition 2 (generate [ i :in [:a :b :c :d :e]] i)) + '@[(:a :b) (:c :d) (:e)])) +(assert (= (mean (generate [i :in [2 3 5 7 11]] i)) + 5.6)) + # And and or # c16a9d846 (assert (= (and true true) true) "and true true")