【问题标题】:Clojure Group Sequential Occurrences - Improve FunctionClojure 组顺序出现 - 改进功能
【发布时间】:2014-10-14 03:53:15
【问题描述】:

我正在尝试对直接出现在彼此旁边的项目进行分组,只要它们都在给定的“白名单”中。分组必须至少包含两个或更多项目。

例如,第一个 arg 是集合,第二个 arg 是白名单。

(group-sequential [1 2 3 4 5] [2 3])
>> ((2 3))

(group-sequential ["The" "quick" "brown" "healthy" "fox" "jumped" "over" "the" "fence"] 
                  ["quick" "brown" "over" "fox" "jumped"])
>> (("quick" "brown") ("fox" "jumped" "over"))

(group-sequential [1 2 3 4 5 6 7] [2 3 6])
>> ((2 3))

这是我想出的:

(defn group-sequential
  [haystack needles]
  (loop [l haystack acc '()]
    (let [[curr more] (split-with #(some #{%} needles) l)]
      (if (< (count curr) 2)
        (if (empty? more) acc (recur (rest more) acc))
        (recur (rest more) (cons curr acc))))))

它有效,但很丑陋。我想知道在 Clojure 中是否有更简单的惯用方法? (在我发现 split-with 之前你应该已经看过 fn 了 :)

我敢打赌,有一个不错的带分区或其他东西的单线,但为时已晚,我似乎无法让它发挥作用。

【问题讨论】:

  • 是什么逻辑决定了“棕色”和“狐狸”是分开的?
  • 啊,你是对的@noisesmith。那是一个错字。我将在两者之间添加“健康”以使其更清晰。

标签: algorithm clojure


【解决方案1】:
(defn group-sequential [coll white] 
  (->> coll
       (map (set white))
       (partition-by nil?)
       (filter (comp first next))))

...Diego Basch's method 的更简洁版本。

【讨论】:

    【解决方案2】:

    这是我的第一次尝试:

    (defn group-sequential [xs wl]
      (let [s (set wl)
            f (map #(if (s %) %) xs)
            xs' (partition-by nil? f)]
        (remove #(or (nil? (first %)) (= 1 (count %))) xs')))
    

    【讨论】:

      【解决方案3】:
      (defn group-sequential
        [coll matches]
        (let [matches-set (set matches)]
          (->> (partition-by (partial contains? matches-set) coll)
               (filter #(clojure.set/subset? % matches-set))
               (remove #(< (count %) 2)))))
      

      【讨论】:

        【解决方案4】:

        好的,我意识到 partition-by 非常接近我正在寻找的东西,所以我创建了这个看起来更符合核心内容的函数。

        (defn partition-if
          "Returns a lazy seq of partitions of items that match the filter"
          [pred coll]
          (lazy-seq
           (when-let [s (seq coll)]
             (let [[in more0] (split-with pred s)
                   [out more] (split-with (complement pred) more0)]
               (if (empty? in)
                 (partition-if pred more)
                 (cons in (partition-if pred more)))))))
        
        (partition-if #(some #{%} [2 3 6]) [1 2 3 4 5 6 7])
        >> ((2 3))
        

        【讨论】:

        • 建议您从假定的通用函数partition-if 中删除(&lt; (count in) 2) 条件。它像拇指酸痛一样突出,并且不在描述性评论中。您始终可以相应地过滤结果。
        • 好点@Thumbnail。我将其更改为 filter empty?,因为有时您会在结果中得到 (() (3 4)),即使在一般情况下,我也不认为这是预期的。想法?
        • 声音。每当(not (pred (first coll))) 时,最初都会出现一个空分区。
        猜你喜欢
        • 2014-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-05
        • 2014-11-29
        • 2015-12-22
        • 2018-10-29
        • 1970-01-01
        相关资源
        最近更新 更多