into或vec:将序列转换回Clojure中的向量 [英] Into or vec: converting sequence back to vector in Clojure
问题描述
我有以下代码在向量中递增每个对的第一个元素:
I have the following code which increments the first element of every pair in a vector:
(vec (map (fn [[key value]] [(inc key) value]) [[0 :a] [1 :b]]))
但是我担心这个代码是不起眼的,因为它首先使用map创建一个序列,然后将它转换回一个向量。
However i fear this code is inelegant, as it first creates a sequence using map and then casts it back to a vector.
:
(into [] (map (fn [[key value]] [(inc key) value]) [[0 :a] [1 :b]]))
在#clojure@irc.freenode.net被告知,使用上面的代码是坏的,因为 into
扩展为(reduce conj [](map-indexed ...) code>,它在过程中产生许多中间对象。然后我被告知,实际上
到不会扩展到
(reduce conj ...)
能够。还测量经过时间显示进入
实际上快于 vec
。
On #clojure@irc.freenode.net i was told, that using the code above is bad, because into
expands into (reduce conj [] (map-indexed ...))
, which produces many intermediate objects in the process. Then i was told that actually into
doesn't expand into (reduce conj ...)
and uses transients when it can. Also measuring elapsed time showed that into
is actually faster than vec
.
所以我的问题是:
- 使用
映射的正确方法是什么?
over vectors? - 当我使用
vec
和到
与向量?
- What is the proper way to use
map
over vectors? - What happens underneath, when i use
vec
andinto
with vectors?
相关但不重复的问题:
- Clojure: sequence back to vector
- How To Turn a Reduce-Realized Sequence Back Into Lazy Vector Sequence
推荐答案
实际上从Clojure 1.4.0,这样做的首选方法是使用 mapv
像 map
,除了它的返回值是一个向量。这是迄今为止最有效的方法,没有不必要的中间分配。
Actually as of Clojure 1.4.0 the preferred way of doing this is to use mapv
, which is like map
except its return value is a vector. It is by far the most efficient approach, with no unnecessary intermediate allocations at all.
Clojure 1.5.0将带来一个新的reducer库, code>,,,
,
drop
等,同时创建向量,可以使用 into []
。
Clojure 1.5.0 will bring a new reducers library which will provide a generic way to map
, filter
, take
, drop
etc. while creating vectors, usable with into []
. You can play with it in the 1.5.0 alphas and in the recent tagged releases of ClojureScript.
对于(vec some-seq)
As for (vec some-seq)
and (into [] some-seq)
, the first ultimately delegates to a Java loop which pours some-seq
into an empty transient vector, while the second does the same thing in very efficient Clojure code. In both cases there are some initial checks involved to determine which approach to take when constructing the final return value.
vec
和 into []
对于小长度(最多32个)的Java数组有显着不同 - 第一个将别名数组(使用它作为新创建的尾向量),并要求数组不被随后修改,以免向量的内容改变(见docstring);后者创建具有新尾部的新向量,并且不关心对数组的未来更改。
vec
and into []
are significantly different for Java arrays of small length (up to 32) -- the first will alias the array (use it as the tail of the newly created vector) and demands that the array not be modified subsequently, lest the contents of the vector change (see the docstring); the latter creates a new vector with a new tail and doesn't care about future changes to the array.
这篇关于into或vec:将序列转换回Clojure中的向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!