按不同尺寸对seq进行分组 - Clojure

时间:2014-08-23 16:00:08

标签: clojure

我有以下数据:

(def letters [:a :b :c :d :e :f :g ])
(def group-sizes [2 3 2])

按尺寸分组字母的惯用方法是什么,以便我得到:

[[:a :b] [:c :d :e] [:f :g]]

感谢。

3 个答案:

答案 0 :(得分:9)

(->> group-sizes
     (reductions + 0)
     (partition 2 1)
     (map (partial apply subvec letters)))

此算法要求输入coll letters为向量,并至少具有所需数量的(apply + group-sizes)元素。它返回与输入向量共享结构的向量的惰性seq(或向量,如果使用mapv)。

由于subvec它们是在O(1)中创建的,因此总时间复杂度应为O(N),其中N为(count group-sizes),与Diegos算法相比,其中N将显着更高{{} 1}}。

答案 1 :(得分:4)

在我开始写答案之后,我注意到Leon Grapenthin's solution与我的几乎相同。

这是我的版本:

(let [end   (reductions + group-sizes)
      start (cons 0 end)]
  (map (partial subvec letters) start end))

Leon Grapenthin's solution的唯一区别在于我使用的是letcons,而不是partitionapply

注意,两个解决方案都懒惰地消耗group-sizes,从而产生一个惰性序列作为输出。

答案 2 :(得分:2)

不一定是最好的方式(例如,您可能想要检查组大小的总和是否与字母大小相同以避免NPE)但这是我的第一个想法:

(defn sp [[f & r] l]
  (when (seq l)
    (cons (take f l)
          (sp r (drop f l)))))

如果您有一个很长的列表并且不想炸毁堆栈,您也可以使用累加器和recur来执行此操作。