I have collection of lists and I want to apply "reduce +" for each list in collection. I think I should combine "apply", "map" and "reduce +", but I can't understand how.
Example:
[[1 2 3] [4 5 3] [2 5 1]] => [6 12 8]
No need for apply. map and reduce will work fine:
(map (partial reduce +) [[1 2 3] [4 5 3] [2 5 1]])
map will call the function on each member of the list and partial simply creates a 'curried' version of reduce that expects one parameter. it could also be written like #(reduce + %) or (fn [lst] (reduce + lst))
Update
You could actually use apply in place of reduce here as well (just not both):
(map (partial apply +) [[1 2 3] [4 5 3] [2 5 1]])
Further Update
If you have any performance concerns, see the comments on this answer for some great tips by #AlexMiller
Related
Below is a bare-bones version of what I'm doing:
(eduction (map inc) (concat [1 2] [3 4]))
; -> (2 3 4 5)
Is there a way to get the same eduction, without having to pay the cost of concat, which creates an intermediate lazy seq?
The following would perhaps already be a bit less wasty, as instead of the lazy seq, we just have a vector, but I wonder if even that can be avoided.
(eduction (comp cat (map inc)) [[1 2] [3 4]])
It may be simplest to process your collections separately and combine the results. There is, in fact, an easy reducers-based solution that does exactly that under the covers.
The clojure.core.reducers namespace has cat, a combining function for fold, that you can repurpose to construct a reducible concatenation of your vectors.
(require '[clojure.core.reducers :as r])
(eduction (map inc) (r/cat [1 2] [3 4]))
;; => (2 3 4 5)
This avoids the lazy sequence used in concat. If you have more than two vectors, you can concatenate them all with (reduce r/cat [] colls) or similar.
This approach did speed up some of the experiments I did, though not your particular example.
You can also do this without the reducer just using the built in cat transducer
(eduction (comp cat (map inc)) [[1 2] [3 4]])
;; => (2 3 4 5)
I would like to create a list of pairs from cols, and patch. cols would have much more elements. Element in patch would be repeated in the pairing.
For example,
(element-wise-patch '(1 3 5 7 9) '(2 4) '())
([1 2] [3 4] [5 2] [7 4] [9 2])
Here is my attempt to implement the semantics. I hope to learn more idiomatic, and simpler solution.
(defn element-wise-patch [cols patch patched]
(if (<= (count cols) (count patch))
(concat patched (map vector cols patch))
(let [[compatible remaining] (split-at (count patch) cols)]
(element-wise-patch remaining patch (concat patched (map vector compatible patch)))))
I feel that there might be already existing construct to do such patching pairing. Also my description might not be proper enough to associate similar solutions.
Please give me some pointer, or just help me define my problem clearer.
Thanks in advance for your help!
Quite simply:
(map vector [1 3 5 7 9] (cycle [2 4]))
Let's say I have a data structure like so:
[[1 2 3] [4 5 6] [[7 8 9] [10 11 12]]]
And what I want to end up with is:
[[1 2 3] [4 5 6] [7 8 9] [10 11 12]]
Is there any function that does this automatically?
Basically I'm converting/transforming a SQL result set to CSV, and there are some rows that will transform to 2 rows in the CSV. So my map function in the normal case returns a vector, but sometimes returns a vector of vectors. Clojure.data.csv needs a list of vectors only, so I need to flatten out the rows that got pivoted.
Mapcat is useful for mapping where each element can expand into 0 or more output elements, like this:
(mapcat #(if (vector? (first %)) % [%]) data)
Though I'm not sure if (vector? (first %)) is a sufficient test for your data.
A different approach using tree-seq:
(def a [[1 2 3] [4 5 6] [[7 8 9] [10 11 12]]])
(filter (comp not vector? first)
(tree-seq (comp vector? first) seq a))
I am stretching to use tree-seq here. Would someone with more experience care to comment on if there is a better way to return only the children other than using what is effectively a filter of (not branch?)
Clojure: Semi-Flattening a nested Sequence answers your question, but I don't want to mark this question as a duplicate of that one, since you're really asking a different question than he was; I wonder if it's possible to move his answer over here.
How to add two collections efficiently in clojure ?
I tried following one. I want to know is there any other method efficient than this.
(reduce #(conj %1 %2) collection01 collection02)
It depends on what you want to achieve. If what you want in the result is a collection of specified type, that contains all element of given collections, then into is appropriate: (into coll1 coll2) returns collection of type (type coll1) with elements from coll1 and coll2.
On the other hand, if you just want to iterate over many collections (i.e. create a sequence of elements in the collections) then it is more efficient to use concat:
user> (concat [1 2 3] (list 4 5 6))
(1 2 3 4 5 6)
use into:
user> (into [1 2 3] [4 5 6])
[1 2 3 4 5 6]
user> (doc into)
-------------------------
clojure.core/into
([to from])
Returns a new coll consisting of to-coll with all of the items of
from-coll conjoined.
nil
I wish to add type data to a clojure vector by adding meta data. What do I need to add to this to achieve this:
(def r (ref [1 2 3]))
Note that I want to add the meta data to [1 2 3]. Is this even the right way of doing this? I mean, should I be adding meta-data to the vector [1 2 3] to "r"?
I think it should be added to 'r':
user=> (def r (ref [1 2 3] :meta {:type "vector"}))
#'user/r
user=> (meta r)
{:type "vector"}