我在询问zipmap
构造的特殊性,却发现我显然做错了。所以我在这个过程中学到了(map vector v u)
。但在此案例之前,我曾使用zipmap来完成(map vector ...)
的工作。它是否有用,因为结果地图足够小,可以整理出来?
以及实际问题:zipmap
有什么用途,以及如何/何时使用它。何时使用(map vector ...)
?
我原来的问题需要原始订单,所以映射任何东西都不是一个好主意。但基本上 - 除了结果对的顺序 - 这两种方法是等价的,因为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)
答案 0 :(得分:37)
当你想要从单独的键和值序列中直接构造一个hashmap 时,使用(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])
需要考虑的其他注意事项:
(into {} (map vector [:k1 :k2 :k3] [10 20 40]))
是一个非常复杂的做zipmap的方式答案 1 :(得分:7)
这些方法或多或少是等同的。当您使用zipmap时,您将获得一个包含键/值对的地图。当您遍历此地图时,您将获得[键值]向量。但是没有定义地图的顺序。使用第一种方法中的“map”构造,可以创建一个包含两个元素的向量列表。订单已定义。
在您的示例中,Zipmap可能效率稍低。我会坚持使用'地图'。
修改:哦,而且zipmap不是懒惰的。所以在你的例子中不使用它的另一个原因。
编辑2 :在您真正需要地图时使用zipmap,例如快速随机基于密钥的访问。
答案 2 :(得分:3)
(zipmap k v)接受两个seq并返回map(而不是保留元素的顺序)
(map vector s1 s2 ...)获取seqs的任何计数并返回seq
当你想将两个seq压缩成地图时,请使用第一个。
当你想将向量(或列表或任何其他seq创建表单)应用于多个seq时,使用第二个。
当您打印文档的多个副本时,与“collate”选项有一些相似之处:)
答案 3 :(得分:3)
两者可能看似相似但实际上却截然不同。
zipmap
创建地图(map vector ...)
创建LazySeq
个n元组(大小为n的向量)这是两种截然不同的数据结构。 虽然2元组的延迟序列可能看起来与地图相似,但它们的表现却截然不同。
假设我们正在映射两个集合,coll1
和coll2
。考虑coll1
具有重复元素的情况。 zipmap
的输出仅包含与coll1
中重复键的最后一次出现相对应的值。 (map vector ...)
的输出将包含2元组,其中包含重复键的所有值。
一个简单的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映射变成了一系列向量。
seq'd映射成为一系列向量,但不一定与(map vector ...)
为了完整性,以下是已排序的seq'd向量:
=> (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])
我认为我们最接近如上所述的陈述是:
如果set
本身(zip map coll1 coll2)
,set
的结果(map vector coll1 coll2)
将等于coll1
结果的set
对于两个据称非常相似的操作,这是很多限定符。 这就是为什么在决定使用哪一个时必须特别小心的原因。 它们非常不同,用途不同,不能互换使用。