【问题标题】:Convert an array of tuples into a hash-map in Clojure在 Clojure 中将元组数组转换为哈希映射
【发布时间】:2011-05-18 17:47:04
【问题描述】:

我有一个元组数组,其中每个元组是一个 2 元组,带有一个键和一个值。将这个元组数组转换为哈希映射的最干净的方法是什么?

【问题讨论】:

    标签: clojure map hashmap tuples


    【解决方案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
    猜你喜欢
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 2011-10-25
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 2012-10-29
    相关资源
    最近更新 更多