【问题标题】:Combine and do calculation two vectors return map Clojure组合并计算两个向量返回映射 Clojure
【发布时间】:2020-06-05 06:18:52
【问题描述】:

我得到了两个向量,[shoes milk shoes][1 3 1],我想要得到的地图是{shoes 2, milk 3}。我试图zipmap 两个向量,只有{shoes 1 milk 3} 显示。如果没有循环和迭代,还有其他方法吗?

【问题讨论】:

  • 向量不是固定的。可能是【鞋奶奶】或者【鞋奶奶鞋花】。相应的向量也发生了变化
  • 请将此信息添加到您的问题中,以便更多人看到。不是每个人都会看 cmets。

标签: dictionary vector clojure zipmap


【解决方案1】:

您还可以为此采用一些不同的解决方案,为项目到数量对生成单项映射,然后将它们与+ 合并:

(let [goods '[shoes milk shoes]
      amounts [1 3 1]]
  (apply merge-with + (map hash-map goods amounts)))

;;=> {milk 3, shoes 2}

【讨论】:

    【解决方案2】:

    您可以通过reduce 做到这一点:

    • 从两个列表中构建键/值元组
    • 累加到map中:将值添加到map中key的value中(或者如果缺少则从0开始(传递nil))
    (let [v1 '[shoes milk shoes]              
          v2 [1 3 1]] 
      (reduce                                                                 
        (fn [m [k v]]                                                   
          (update m k (fnil + 0) v))                        
        {}                     
        (map vector v1 v2)))
    ; → {shoes 2, milk 3}                                                                                                                                                                     
    

    【讨论】:

      【解决方案3】:

      我非常喜欢@leetwinski 的解决方案。

      其实,为了以后解决类似的问题, 我建议,首先收集列表中所有键的值 - 按它们出现的顺序:

      (defn vecs2hash 
        [keys values]
        (apply merge-with concat (map (fn [k v] {k (list v)}) keys values)))
      

      然后:

      (def hm (vecs2hash '[shoes milk shoes milk] [1 4 2 3]))
      
      hm
      ;; => {milk (4 3), shoes (1 2)}
      

      然后,可以根据需要编写一个处理每个收集到的元素的函数。

      定义一个新函数来总结列表中的所有值:

      (defn sum-up-value
        [val]
        (apply + val))
      

      定义一个辅助函数以应用该辅助函数来处理所有值列表:

      (defn apply-to-each-value
        [fun hm]
        (apply hash-map (interleave (keys hm) (map fun (vals hm)))))
      

      所以在你的情况下:

      (apply-to-each-value sum-up-values hm)
      ;; {milk 7, shoes 3}
      

      【讨论】:

      • flatten 几乎永远不会好,当您不确定values 类型是什么时:(vecs2hash [:a :b :a] [[1 2] [2 3] [3 4]]) => {:b ([2 3]), :a (1 2 3 4)}。我会建议这个:(defn vecs2hash [keys values] (apply merge-with concat (map (fn [k v] {k [v]}) keys values)))
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多