在 Clojure 中将元组数组转换为哈希映射
Posted
技术标签:
【中文标题】在 Clojure 中将元组数组转换为哈希映射【英文标题】:Convert an array of tuples into a hash-map in Clojure 【发布时间】:2011-05-18 17:47:04 【问题描述】:我有一个元组数组,其中每个元组是一个 2 元组,带有一个键和一个值。将这个元组数组转换为哈希映射的最干净的方法是什么?
【问题讨论】:
【参考方案1】:地图是一系列 MapEntry 元素。每个 MapEntry 都是一个键和值的向量。问题中的元组已经采用 MapEntry 的形式,这使事情变得方便。 (这也是为什么into
解决方案很好的原因。)
user=> (reduce conj [[:a 1] [:b 2]])
:b 2, :a 1
【讨论】:
感谢您的精彩解释!所以只有 2 个元素的向量是 MapEntry,因此 (into [[:a 1] :b 2]) 会起作用,但是 (into ['( :a 1 ) :b 2]) 会不起作用。它收到“java.lang.ClassCastException:clojure.lang.Keyword 无法转换为 java.util.Map$Entry”的错误。我想知道为什么 Clojure 不能在这种情况下以相同的方式处理所有 2 个元素序列。它将使其更加一致。没有的原因是什么?【参考方案2】:user=> (into [[:a 1] [:b 2]])
:a 1, :b 2
【讨论】:
请注意,这也适用于二元素数组的数组——您只需在数组参数周围添加一个(map vec ...)
:(into (map vec an-array-of-two-element-arrays))
。
再说一次,你在使用 Clojure 时经常遇到的那些“duh”时刻之一。很好的答案。
不过比较贵。
@MichałMarczyk 我不明白......如果你已经有一个数组数组,为什么要在它们上面映射vec
?我认为vec
只是将数组保持原样......
为什么必须是向量,为什么两个元素列表的列表不起作用?【参考方案3】:
user=> (def a [[:a 4] [:b 6]])
user=> (apply hash-map (flatten a))
:a 4, :b 6
【讨论】:
flatten
对于这个问题来说太过分了。您可以利用 MapEntry(键和值的向量)形式的元组。
永远不要在这样的情况下使用flatten
:如果它们恰好是数据结构,它也会很高兴地扁平化所有键和值!【参考方案4】:
假设“tupel”表示“二元数组”:
(reduce
(fn [m tupel]
(assoc m
(aget tupel 0)
(aget tupel 1)))
array-of-tupels)
【讨论】:
不错。如果您的(对 OP)“数组”实际上是一个 seq,而不是(aget t n)
,您可以使用 (t n)
,这有点漂亮。
(t n)
不适用于序列。它与向量有关。但是你可以简单地使用(into array-of-vectors)
而不是reduce
。以上是关于在 Clojure 中将元组数组转换为哈希映射的主要内容,如果未能解决你的问题,请参考以下文章