Clojure Group序贯发生 - 改进功能

时间:2014-10-14 03:53:15

标签: algorithm clojure

我试图将直接出现在彼此旁边的项目分组,只要它们分别位于给定的"白名单"中。分组必须至少包含两个或更多项目。

例如,第一个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中用它做一个更简单的惯用方法吗? (在我发现拆分之前你应该看过fn :)。

我敢打赌,这是一个不错的单行内容,有分区或者其他东西,但是它已经很晚了,我似乎无法让它发挥作用。

4 个答案:

答案 0 :(得分:3)

(defn group-sequential [coll white] 
  (->> coll
       (map (set white))
       (partition-by nil?)
       (filter (comp first next))))

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

答案 1 :(得分:0)

这是我的第一次尝试:

(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')))

答案 2 :(得分:0)

好的,我意识到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))

答案 3 :(得分:0)

(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)))))