假设我有一些这样的数据:
{:gender "male" :name "Gabriel" :age 25}
{:gender "female" :name "Jane" :age 25}
{:gender "female" :name "Alice" :age 22}
我如何迭代这些数据并基于哈希嵌套它们,所以它可以是这样的:
[:25 [{:gender "male" :name "Gabriel" :age 25}, {:gender "female" :name "Jane" :age 25}] :22[ {:gender "female" :name "Alice" :age 22} ]
我已经尝试使用地图和向量,我可以使用 doseq 迭代数据,但是我可以嵌套数据有很多麻烦。任何人都可以为此带来一些启示吗?非常感谢你。
答案 0 :(得分:4)
一个常见的模式是将这个问题分成几部分,为每个部分创建一个表达式,然后将它们连接在一起(->>
发音为"线程结束"并且它传递输出每个表达式到最后一个参数位置的下一个表达式)在这种情况下,我看到三个阶段:
可以写成:
user> (def my-data [{:gender "male" :name "Gabriel" :age 25}
{:gender "female" :name "Jane" :age 25}
{:gender "female" :name "Alice" :age 22}])
#'user/my-data
user> (->> my-data
(sort-by :age)
(partition-by :age)
(map (fn [group] [(keyword (str (:age (first group)))) group]))
reverse)
([:25 ({:gender "male", :name "Gabriel", :age 25}
{:gender "female", :name "Jane", :age 25})]
[:22 ({:gender "female", :name "Alice", :age 22})])
最后的反向只是按降序排列,以便与您想要的输出样式相匹配。重要的想法是制作几个小表达式,每个表达式都会解决问题,然后组成它们来解决整个问题。
您可能还想了解地图上的group-by
功能,它会采用一系列地图,并且几乎可以直接解决您的问题。
user> (group-by :age my-data)
{25 [{:gender "male", :name "Gabriel", :age 25}
{:gender "female", :name "Jane", :age 25}],
22 [{:gender "female", :name "Alice", :age 22}]}
它返回一个地图而不是序列(或矢量),并且不会将键转换为关键字。出于实际原因,它可能是大多数此类问题的答案。同样重要的是组成较小的解决方案,以便更方便地解决更大的问题。
答案 1 :(得分:0)
以下代码完全符合您的要求:
(def data
[{:gender "male" :name "Gabriel" :age 25}
{:gender "female" :name "Jane" :age 25}
{:gender "female" :name "Alice" :age 22}])
(vec (mapcat identity (group-by :age data)))
[25 [{:gender "male", :name "Gabriel", :age 25}
{:gender "female", :name "Jane", :age 25}]
22 [{:gender "female", :name "Alice", :age 22}]]