使用clojure从地图中删除键

时间:2016-09-30 06:09:02

标签: clojure

我有一张地图

({:A 1.0, :B 2.0} {:A 3.0, :B 1.0} {:A 4.0, :B 1.0} {:A 12.0, :B 2.0} {:A 3.0, :B 1.0})

我只想要返回值而不是键。我尝试使用vals函数,但只有在{:A 1.0, :B 2.0}形式时才使用。

还尝试使用for循环,然后使用peek函数。但是当我使用nil函数时,我得到peek,因为这里的第一个元素是map。

我想要退回:{[1.0 2.0][3.0 1.0][3.0 1.0][4.0 1.0][12.0 2.0][3.0 1.0]}

3 个答案:

答案 0 :(得分:4)

这里有一张地图列表。要获得vals,您可以map

user=> (map vals '({:A 1.0, :B 2.0} {:A 3.0, :B 1.0} {:A 4.0, :B 1.0} {:A 12.0, :B 2.0} {:A 3.0, :B 1.0}))
((1.0 2.0) (3.0 1.0) (4.0 1.0) (12.0 2.0) (3.0 1.0))

另请注意,地图不是有序的(它们对于小型密钥集看起来是有序的)。因此,如果您想确保获得:A然后:B的值,则可以使用juxt和所需的密钥:

user=> (map (juxt :A :B) '({:A 1.0, :B 2.0} {:A 3.0, :B 1.0} {:A 4.0, :B 1.0} {:A 12.0, :B 2.0} {:A 3.0, :B 1.0}))
([1.0 2.0] [3.0 1.0] [4.0 1.0] [12.0 2.0] [3.0 1.0])

答案 1 :(得分:3)

  

我想要归还:

     

{[1.0 2.0][3.0 1.0][3.0 1.0][4.0 1.0][12.0 2.0][3.0 1.0]}

不,你没有!你想要返回

[[1.0 2.0][3.0 1.0][3.0 1.0][4.0 1.0][12.0 2.0][3.0 1.0]]

或等效名单。

如果我们有

(def data [{:A 1.0,:B 2.0} {:A 3.0,:B 1.0} {:A 4.0,:B 1.0}            {:A 12.0,:B 2.0} {:A 3.0,:B 1.0}])

然后

(map vals data)
;((1.0 2.0) (3.0 1.0) (4.0 1.0) (12.0 2.0) (3.0 1.0))

正如Alan Thompson所观察到的,此解决方案不足,因为它不保证每个子列表的顺序。

答案 2 :(得分:0)

您需要澄清您的问题。您的输入不是地图,而是一系列地图。你想要一个矢量序列的结果。

使用矢量符号(vec of vec,vec vec)编写它们。请注意,您纠正的建议答案中也有错误!

(ns tst.clj.core
  (:use clj.core
        clojure.test ))

(def vec-of-maps [ {:A 1.0, :B 2.0} {:A 3.0, :B 1.0} {:A 4.0, :B 1.0} {:A 12.0, :B 2.0} {:A 3.0, :B 1.0} ] )

(def answer      [ [1.0 2.0]         [3.0 1.0]         [4.0 1.0]         [12.0 2.0]       [3.0 1.0] ] )

(defn ff
  [data]
  (forv [curr-map data]
    (vec (vals curr-map))))

(deftest tt
  (is (= answer (ff vec-of-maps))))

请注意,如果我们只关心平等,我们并不需要将结果强制转换为向量。我们可以使用下面的f2并获得一系列序列作为输出,它等于vec的vec:

(defn f2
  [data]
  (for [curr-map data]
    (vals curr-map)))