Vector Into或vec:在Clojure中将序列转换回矢量

Vector Into或vec:在Clojure中将序列转换回矢量,vector,clojure,sequence,Vector,Clojure,Sequence,我有以下代码,它增加向量中每对的第一个元素: (vec (map (fn [[key value]] [(inc key) value]) [[0 :a] [1 :b]])) 然而,我担心这段代码是不雅观的,因为它首先使用map创建一个序列,然后将其转换回向量 考虑这个类比: (into [] (map (fn [[key value]] [(inc key) value]) [[0 :a] [1 :b]])) 在#clojure@irc.freenode.net有人告诉我,使用上面的代码是

我有以下代码,它增加向量中每对的第一个元素:

(vec (map (fn [[key value]] [(inc key) value]) [[0 :a] [1 :b]]))
然而,我担心这段代码是不雅观的,因为它首先使用map创建一个序列,然后将其转换回向量

考虑这个类比:

(into [] (map (fn [[key value]] [(inc key) value]) [[0 :a] [1 :b]]))
在#clojure@irc.freenode.net有人告诉我,使用上面的代码是不好的,因为
into
扩展成
(reduce conj[](映射索引…)
,在这个过程中会产生许多中间对象。然后我被告知,实际上,
并不扩展到
(reduce conj…
),而是在可能的情况下使用瞬变。同时测量经过的时间表明,
进入
实际上比
vec

因此,我的问题是:

  • 在向量上使用
    map
    的正确方法是什么
  • 当我将
    vec
    与向量一起使用时,下面会发生什么
  • 相关但不重复的问题:


    实际上,从Clojure 1.4.0开始,执行此操作的首选方法是使用
    mapv
    ,它与
    map
    类似,只是其返回值是向量。这是迄今为止最有效的方法,没有任何不必要的中间分配

    Clojure 1.5.0将引入一个新的简化程序库,该库将提供一种通用的方法,在创建向量时,将
    映射到[]
    过滤器
    获取
    删除
    等。您可以在1.5.0 alphas和最近标记的ClojureScript版本中使用它

    至于
    (vec some seq)
    (into[]some seq)
    ,第一个最终委托给一个Java循环,该循环将
    some seq
    注入一个空的瞬时向量,而第二个循环在非常高效的Clojure代码中做同样的事情。在这两种情况下,都需要进行一些初始检查,以确定在构造最终返回值时采用哪种方法


    vec
    into[]
    对于长度较小(最多32个)的Java数组有很大的不同——第一个数组将别名该数组(将其用作新创建的向量的尾部),并要求以后不要修改数组,以免向量的内容发生变化(参见docstring);后者创建了一个带有新尾巴的新向量,不关心阵列将来的更改。

    谢谢
    (mapv f args)
    (into(vector)(mapfargs))要简洁得多。
    这个答案还是真实的吗?我对ClojureScript最感兴趣。谢谢
    mapv
    仍然存在,如果您想在向量中的seqable集合上累积映射函数的结果,这是最好的方法。减缩器仍然存在,但是Clojure现在有传感器,它非常适合使用更复杂的转换构建向量和其他集合–
    (转换为[](map inc)input coll)等。如果您可以通过
    Clojure.core.reducer/fold从并行化中获益,减缩器仍然是最佳选择,但这与ClojureScript无关。这是否仍然适用于
    vec
    和“小数组”?我做了以下实验:``(defmy-a(int-array[123]))(defmy-v(vecmy-a))my-v;=>[1 2 3](aset my-a 1 10))(java.util.array/toString my-a);=>"[1, 10, 3]" ;=> my-v[1 2 3]``@JurajMartinka确实如此,但仅适用于
    对象的数组
    。您的是一个基本数组,因此当您对其调用
    vec
    时,它的所有项都将被装箱并复制到相同长度的新对象数组中。这是因为由
    vec
    vector
    返回并由文本语法
    […]
    创建的持久向量始终存储对象引用。内置了一种独特的向量类型,可以保存原语项,请参见
    clojure.core/vector of
    ;注意。目前使用它通常需要对访问进行装箱,因此应该仔细评估它是否合适,甚至对于原语也不默认。