【问题标题】:Untuple a Clojure sequence取消一个 Clojure 序列
【发布时间】:2015-09-09 19:59:19
【问题描述】:

我有一个优先删除重复数据的函数,因此我想到了使用 flambo 函数在 clojure 中实现该解决方案:

  1. 从数据集中,使用group-by,对重复项进行分组(即基于指定的:key

  2. 给定 :val 作为输入,使用 filter 检查每行的某些值是否等于 :val

  3. 使用映射到 untuple 重复项以返回单个向量(虽然不太确定这是否正确,但我尝试使用 flat-map 没有任何运气)

对于示例数据集

(def rdd
   (f/parallelize sc [ ["Coke" "16" ""] ["Pepsi" "" "5"] ["Coke" "2" "3"] ["Coke" "" "36"] ["Pepsi" "" "34"] ["Pepsi" "25" "34"]]))

我试过这个:

(defn dedup-rows
 [rows input]
 (let [{:keys [key-col col val]} input  
      result (-> rows
               (f/group-by (f/fn [row]
                            (get row key-col)))
              (f/values)
              (f/map (f/fn [rows]
                (if (= (count rows) 1)
                  rows
                  (filter (fn [row]
                            (let [col-val (get row col)
                                  equal? (= col-val val)]
                              (if (not equal?)
                               true
                               false))) rows)))))]
    result))

如果我这样运行这个函数:

(dedup-rows rdd {:key-col 0 :col 1 :val ""})

它产生

;=> [(["Pepsi" 25 34]), (["Coke" 16 ] ["Coke" 2 3])]]

我不知道还要做什么来处理结果以产生

;=> [["Pepsi" 25 34],["Coke" 16 ],["Coke" 2 3]]

我尝试将f/map f/untuple 作为-> 宏中的最后一个形式,但没有成功。

有什么建议吗?如果有其他方法可以解决这个问题,我将不胜感激。 谢谢。

PS:分组时

;=> [[["Pepsi" "" 5], ["Pepsi" "" 34], ["Pepsi" 25 34]], [["Coke" 16 ""], ["Coke" 2 3], ["Coke" "" 36]]]

对于每个组,具有"" 的行被认为是重复的,因此会从组中删除。

【问题讨论】:

  • @zero323,请帮我解决这个问题。谢谢!

标签: clojure rdd flambo


【解决方案1】:

查看flambo readme,有一个flat-map函数。这是一个有点不幸的命名,因为 Clojure 等价物被称为 mapcat。这些函数获取每个映射结果 - 它必须是一个序列 - 并将它们连接在一起。另一种思考方式是,它将最终序列扁平化一个级别。

我无法对此进行测试,但我认为您应该将 f/map 替换为 f/flat-map

【讨论】:

    【解决方案2】:

    按照@TheQuickBrownFox 的建议,我尝试了以下方法

    (defn dedup-rows
    [rows input]
    (let [{:keys [key-col col val]} input  
      result (-> rows
               (f/group-by (f/fn [row]
                            (get row key-col)))
              (f/values)
              (f/map (f/fn [rows]
                (if (= (count rows) 1)
                  rows
                  (filter (fn [row]
                            (let [col-val (get row col)
                                  equal? (= col-val val)]
                              (if (not equal?)
                               true
                               false))) rows)))
               (f/flat-map (f/fn [row]
                               (mapcat vector row)))))]
      result))
    

    而且似乎有效

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-28
      • 2012-01-13
      • 2015-10-25
      相关资源
      最近更新 更多