Clojure 何时使用“zipmap”和何时使用“map vector”?
我问了一下zipmap结构的特殊性,结果发现我显然做错了。所以我在这个过程中学习了Clojure 何时使用“zipmap”和何时使用“map vector”?,clojure,Clojure,我问了一下zipmap结构的特殊性,结果发现我显然做错了。所以我在这个过程中学习了(map vector v u)。但在此之前,我使用zipmap做了(映射向量…)的工作。因为生成的地图足够小,可以进行分类,所以它起作用了吗 以及实际问题:zipmap有什么用途,以及如何/何时使用它。以及何时使用(映射向量…? 我的原始问题需要原始顺序,所以映射任何东西都不是一个好主意。但基本上——除了结果对的顺序之外——这两种方法是等效的,因为seq'd映射成为一个向量序列 (for [pair (map v
(map vector v u)
。但在此之前,我使用zipmap做了(映射向量…
)的工作。因为生成的地图足够小,可以进行分类,所以它起作用了吗
以及实际问题:zipmap
有什么用途,以及如何/何时使用它。以及何时使用(映射向量…
?
我的原始问题需要原始顺序,所以映射任何东西都不是一个好主意。但基本上——除了结果对的顺序之外——这两种方法是等效的,因为seq
'd映射成为一个向量序列
(for [pair (map vector v (rest v))]
( ... )) ;do with (first pair) and (last pair)
(for [pair (zipmap v (rest v))]
( ... )) ;do with (first pair) and (last pair)
这些方法或多或少是等效的。当您使用zipmap时,您会得到一个带有键/值对的映射。当你在这个地图上迭代时,你会得到[key-value]向量。但是,地图的顺序没有定义。在第一个方法中使用“map”构造,可以创建包含两个元素的向量列表。顺序已定义 在您的示例中,Zipmap可能效率较低。我会坚持使用“地图” 编辑:哦,zipmap并不懒惰。所以在你的例子中不使用它的另一个原因 编辑2:当您确实需要映射时使用zipmap,例如用于基于随机键的快速访问。当您希望直接从单独的键和值序列构建哈希映射时使用(zipmap…)。输出为hashmap:
(zipmap [:k1 :k2 :k3] [10 20 40])
=> {:k3 40, :k2 20, :k1 10}
尝试合并多个序列时使用(映射向量…)。输出是向量的惰性序列:
(map vector [1 2 3] [4 5 6] [7 8 9])
=> ([1 4 7] [2 5 8] [3 6 9])
需要考虑的一些额外注意事项:
- Zipmap只能处理两个输入序列(键+值),而map vector可以处理任意数量的输入序列。如果您的输入序列不是键值对,那么这可能是一个很好的提示,您应该使用map vector而不是zipmap
- zipmap将比使用map vector更高效、更简单,然后从键/值对创建hashmap-例如,
是一种非常复杂的zipmap方法(到{}(map vector[:k1:k2:k3][10 20 40])
- map vector是惰性的-因此它会带来一些额外的开销,但在实际需要惰性的情况下非常有用(例如,处理无限序列时)
- 您可以执行(seq(zipmap…)来获得一个类似于(map vector…)的键值对序列,但是请注意,这可能会对键值对序列重新排序(因为中间hashmap是无序的)
打印多份文档时,选项“collate”有一些相似之处:)这两个选项可能看起来相似,但实际上非常不同
创建地图zipmap
创建n元组的(映射向量…
(大小为n的向量)LazySeq
coll1
和coll2
。考虑案例<代码> COL1有重复的元素。zipmap
的输出将只包含与coll1
中重复键的最后一次出现相对应的值。(映射向量…
的输出将包含两个元组,其中包含重复键的所有值
一个简单的REPL示例:
=> (zipmap [:k1 :k2 :k3 :k1] [1 2 3 4])
{:k3 3, :k2 2, :k1 4}
=>(map vector [:k1 :k2 :k3 :k1] [1 2 3 4])
([:k1 1] [:k2 2] [:k3 3] [:k1 4])
考虑到这一点,我们不难看出以下假设的危险性:
但基本上——除了结果对的顺序之外——这两种方法是等价的,因为seq'd映射变成了向量序列
(for [pair (map vector v (rest v))]
( ... )) ;do with (first pair) and (last pair)
(for [pair (zipmap v (rest v))]
( ... )) ;do with (first pair) and (last pair)
序列映射成为向量序列,但不一定与(映射向量…
为完整起见,以下是排序后的矢量:
=> (sort (seq (zipmap [:k1 :k2 :k3 :k1] [1 2 3 4])))
([:k1 4] [:k2 2] [:k3 3])
=> (sort (seq (map vector [:k1 :k2 :k3 :k1] [1 2 3 4])))
([:k1 1] [:k1 4] [:k2 2] [:k3 3])
我认为我们最接近于上述陈述的是:
如果coll1
本身是set,则(zip-map-coll1-coll2)
结果的set
将等于(map-vector-coll1-coll2)
结果的set
这是两个假设非常相似的操作的许多限定符。
这就是为什么在决定使用哪一种时必须特别小心的原因。
它们非常不同,用途不同,不应互换使用。我一直使用的zipmap
的另一个用途是用地图矢量创建地图。。考虑<代码>(ZIPMAP(MAP:ID数据))< /代码>,其中数据是一个映射向量,每一个都包含一个唯一的<代码>:ID < /代码>键/值对。