【问题标题】:Clojure iteration and nesting dataClojure 迭代和嵌套数据
【发布时间】:2017-05-25 23:58:05
【问题描述】:

假设我有一些这样的数据:

{: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} ]

我已经尝试使用 ma​​ps 和 vectors 并且我能够使用 doseq 遍历数据,但我有一个嵌套数据很麻烦。任何人都可以对此有所启发吗?非常感谢。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    一种常见的模式是将问题拆分为多个部分,为每个部分创建一个表达式,然后将它们连接在一起(->> 发音为“thread last”,它将每个表达式的输出传递给最后一个参数位置)在这种情况下,我看到三个阶段:

    1. 按年龄对它们进行排序,以获得彼此相邻的相似年龄
    2. 按年龄将序列分成块
    3. 将每个组格式化为 [age-in-group whole-group

    可以写成:

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

    它返回一个映射而不是序列(或向量),并且不会将键转换为关键字。出于实际原因,它可能是大多数此类问题的答案。同样重要的部分是组合较小的解决方案以方便解决较大的问题。

    【讨论】:

    • 不仅仅是“非常接近”:我想说这正是解决方案。正如您所注意到的(数字而不是关键字),它产生的输出与问题中所要求的不同。但是数字在这里使用是正确的!每当我看到有人要求 :25 作为映射键时,这是因为他们认为只有关键字才能成为映射键,而不是因为他们真正理解这意味着什么并想要它。
    • 非常感谢,先生;这正是我所需要的。如果可以的话,我一定会付给你一杯啤酒。
    • 支持也可以,如果您在加利福尼亚州的圣克鲁斯地区也可以喝啤酒 ;-)
    • 我一看到你的回答就投了赞成票,再次感谢你。
    【解决方案2】:

    下面的代码正是你想要的:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-05
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多