diff --git a/docs/language/api.rst b/docs/language/api.rst index 2313921..ff301ae 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -1250,3 +1250,20 @@ infinite series without consuming infinite amount of memory. ... (while True (yield (.randint random low high)))) => (list-comp x [x (take 15 (random-numbers 1 50))])]) [7, 41, 6, 22, 32, 17, 5, 38, 18, 38, 17, 14, 23, 23, 19] + +zipwith +------- + +`zipwith` zips multiple lists and maps the given function over the result. It is equilavent to calling `zip`, followed by calling `map` on the result. + +In the following example, `zipwith` is used to add the contents of two lists together. The equilavent `map` and `zip` calls follow. + +.. code-block:: clj + + => (import operator.add) + + => (zipwith operator.add [1 2 3] [4 5 6]) ; using zipwith + [5, 7, 9] + + => (map operator.add (zip [1 2 3] [4 5 6])) ; using map+zip + [5, 7, 9] diff --git a/hy/core/language.hy b/hy/core/language.hy index d8b0df8..19e8486 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -345,10 +345,16 @@ (_numeric_check n) (= n 0)) +(defn zipwith [func &rest lists] + "Zip the contents of several lists and map a function to the result" + (do + (import functools) + (map (functools.partial (fn [f args] (apply f args)) func) (apply zip lists)))) + (def *exports* '[calling-module-name coll? cons cons? cycle dec distinct disassemble drop drop-while empty? even? every? first filter flatten float? gensym identity inc instance? integer integer? integer-char? iterable? iterate iterator? list* macroexpand macroexpand-1 neg? nil? none? nth numeric? odd? pos? remove repeat repeatedly rest second - some string string? take take-nth take-while zero?]) + some string string? take take-nth take-while zero? zipwith]) diff --git a/hy/core/macros.hy b/hy/core/macros.hy index ff497b4..8e3c21a 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -199,3 +199,4 @@ (.append ret `(setv ~name ~main))) ret)) + diff --git a/tests/native_tests/core.hy b/tests/native_tests/core.hy index c973948..1a6ea61 100644 --- a/tests/native_tests/core.hy +++ b/tests/native_tests/core.hy @@ -470,3 +470,12 @@ (assert-equal res [None None]) (setv res (list (take-while (fn [x] (not (none? x))) [1 2 3 4 None 5 6 None 7]))) (assert-equal res [1 2 3 4])) + +(defn test-zipwith [] + "NATIVE: testing the zipwith function" + (import operator) + (setv res (zipwith operator.add [1 2 3] [3 2 1])) + (assert-equal (list res) [4 4 4]) + (setv res (zipwith operator.sub [3 7 9] [1 2 4])) + (assert-equal (list res) [2 5 5])) +