【问题标题】:Better ways to traverse a map of maps遍历地图的更好方法
【发布时间】:2012-06-21 13:16:32
【问题描述】:

我正在做一些数据分析聚合,这是我的数据结构:

{
12300 {
   views {
       page-1 {
          link-2  40
          link-6  9
       }
       page-7 {
          link-3  9
          link-11 8
       }
   }
   buttons {
       page-1 {
          link-22 2
       }
   }
}
34000      ....
}

其中 12300、34000 是时间值。

我想做的是遍历该数据结构并将条目插入数据库,如下所示:

insert into views (page, link, hits, time) values (page-1, link-2, 40, 12300)
insert into views (page, link, hits, time) values (page-1, link-6, 9, 12300)

什么是惯用的编码方式?我是否使数据结构复杂化?您有什么更好的方法来收集数据吗?

【问题讨论】:

    标签: algorithm clojure jvm analytics


    【解决方案1】:

    假设你有一个来自 clojure.java.jdbc 的 jdbc 连接,这应该接近你想要的。

    (jdbc/do-prepared "INSERT INTO views (page, link, hits, time) VALUES (?, ?, ?, ?)"
                      (for [[time data] m
                            [data-type page-data] data
                            [page links] page-data
                            [link hits] links]
                        [page link hits time]))
    ;; why aren't we using data-type, eg buttons?
    

    编辑澄清问题

    (let [m '{12300 {views {page-1 {link-2  40
                                    link-6  9}
                            page-7 {link-3  9
                                    link-11 8}}
                     buttons {page-1 {link-22 2}}}
              34000 {views {page-2 {link-2 5}}}}]
      (doseq [[table rows] (group-by :table (for [[time table] m
                                                  [table-name page-data] table
                                                  [page links] page-data
                                                  [link hits] links]
                                              {:table table-name, :row [page link hits time]}))]
        (jdbc/do-prepared (format "INSERT INTO %s (page, link, hits, time) VALUES (?, ?, ?, ?)" table)
                          (map :row rows))))
    

    【讨论】:

    • 天哪!那是完全邪恶的!谢谢。但没有得到你的;;评论。为什么不使用doseq?
    • 您只想做一件事 - 具有多个值的插入。为什么要使用doseq?我的评论是指出您未使用的地图中有数据:buttonsviews 显示为键,但不会出现在您的插入语句中。
    • 按钮和视图将是表格,因此并非所有数据都将在同一个表格中结束。但现在我可以使用 core.match 或 multimethods 保存到不同的表中。
    • 我添加了一个以您想要的方式处理多个表的版本。当您可以使用序列时,core.match 和 multimethods 似乎就像将非常大的圆钉插入方孔。
    【解决方案2】:

    简单的解决方案:利用您正在使用地图的事实,并使用获取、关联功能来查看/更改数据。请参阅以下示例:

    http://clojuredocs.org/clojure_core/clojure.core/get-in http://clojuredocs.org/clojure_core/clojure.core/assoc-in

    高级解决方案:使用功能性拉链。这允许您以功能方式遍历和更改树状结构。

    这里有一个例子: http://en.wikibooks.org/wiki/Clojure_Programming/Examples/API_Examples/Advanced_Data_Structures#zipper

    如果您有特殊的数据结构,而不是地图的地图,您可以自己创建一个拉链,只需实现 3 个必需的方法。之后,所有 zipper 函数也将适用于您的数据结构。

    【讨论】:

      猜你喜欢
      • 2015-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-23
      • 1970-01-01
      • 2023-03-11
      相关资源
      最近更新 更多