I have a map of the form
{[3.0 4.0][2.0 7.0][7.0 3.0][4.0 6.0][1.0 4.0][5.0 6.0][4.0 9.0][5.0 11.0][4.0 16.0]}
I want to group the second key in specific ranges like
((1-5)(6-10)(11-15)..)
The result should be
{{[3.0 4.0][7.0 3.0][1.0 4.0]}
{[2.0 7.0][4.0 6.0][5.0 6.0][4.0 9.0]}
{[5.0 11.0][4.0 16.0]}}
I have implemented using peek but have failed. How can I achieve this result?
You are confusing the result of your previous question. The output of that question (and input to this one) is a set like #{...}, not a map like {...}. Each element of the set is a length-2 vector like [3 4].
The most straightforward solution is to filter each search range like so:
(ns clj.core
(:require [tupelo.core :as t]
[datascript.core :as d]
[clojure.set :as set] ))
(t/refer-tupelo)
(def data
#{ [3.0 4.0] [2.0 7.0] [7.0 3.0] [4.0 6.0] [1.0 4.0] [5.0 6.0] [4.0 9.0] [5.0 11.0] [4.0 16.0] } )
(println "1-5:" (filter #(<= 1 (second %) 5) data))
;=> 1-5: ([3.0 4.0] [1.0 4.0] [7.0 3.0])
or we could write a loop:
(newline)
(doseq [idx (range 5)]
(let [upper (* (inc idx) 5)
lower (- upper 4) ]
(print (format "[%d..%d] => " lower upper))
(println (filter #(<= 1 (second %) 5) data))))
[1..5] => ([3.0 4.0] [1.0 4.0] [7.0 3.0])
[6..10] => ([4.0 9.0] [2.0 7.0] [4.0 6.0] [5.0 6.0])
[11..15] => ([5.0 11.0])
[16..20] => ([4.0 16.0])
[21..25] => ()
Note that I fixed the data so it is a set, not a map.
You could also use group-by
:
(def result4 (into (sorted-map)
(group-by #(-> % second dec (quot 5)) data)))
(newline)
(pretty result4)
{0.0 [[3.0 4.0] [1.0 4.0] [7.0 3.0]],
1.0 [[4.0 9.0] [2.0 7.0] [4.0 6.0] [5.0 6.0]],
2.0 [[5.0 11.0]],
3.0 [[4.0 16.0]]}
and you can pull out the values like
(newline)
(pp/pprint (vals result4))
([[3.0 4.0] [1.0 4.0] [7.0 3.0]]
[[4.0 9.0] [2.0 7.0] [4.0 6.0] [5.0 6.0]]
[[5.0 11.0]]
[[4.0 16.0]])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.