joey
joey

Reputation: 359

Removing keys from a map using clojure

I have a map in the form

({: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})

I just want only the values to be returned but not the keys.I tried using vals function, but is used only if it is of the form {:A 1.0, :B 2.0}.

Also tried using for loop and then use peek function. But I am getting nil when I use peek function, as the first element here is map.

I want to return this: {[1.0 2.0][3.0 1.0][3.0 1.0][4.0 1.0][12.0 2.0][3.0 1.0]}.

Upvotes: 0

Views: 399

Answers (3)

Thumbnail
Thumbnail

Reputation: 13483

I want to return this:

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

No you don't! You want to return

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

or the equivalent lists.

If we have

(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}])

then

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

As Alan Thompson observes, this solution falls short, as it doesn't guarantee the order of each sub-list.

Upvotes: 3

Alan Thompson
Alan Thompson

Reputation: 29984

You need to clarify your question. Your input is not a map, it is a sequence of maps. You want a result that is a sequence of vectors.

Write them both using vector notation (vec of maps, vec of vecs). Note you also had an error in your proposed answer that I corrected!

(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))))

Note that, if we only care about equality, we don't really need to force the result into vectors. We could use f2 below and get a sequence of sequences as output, which is equal to a vec of vecs:

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

Upvotes: 0

cfrick
cfrick

Reputation: 37073

You have a list of maps here. To get the vals you can map it

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))

Also note, that maps are not ordered (they appear ordered for small key sets). So if you want to make sure, that you get the values for :A and then :B you can use juxt and the keys you want:

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])

Upvotes: 4

Related Questions