我写了这个函数来做这个(比说明更容易显示):
(split 2 (list 1 2 3 4 5 6))
=> ((1 2) (2 3) (3 4) (4 5) (5 6))
(defn split [n xs]
(if (> (count xs) (dec n))
(cons (take n xs) (split n (rest xs)))
'()))
Run Code Online (Sandbox Code Playgroud)
据我所知,在Clojure中,列表并不是唯一的第一类数据结构.编写这种数据结构不可知是否有意义?无论如何,我的实施是最有效的,如果不是,我将如何使其更有效和/或惯用?
谢谢!
Ham*_*aya 21
你可以使用内置的分区功能,
(partition 2 1 (list 1 2 3 4 5 6))
=> ((1 2) (2 3) (3 4) (4 5) (5 6))
Run Code Online (Sandbox Code Playgroud)
适用于任何序列.
clojure.core/partition
([n coll] [n step coll] [n step pad coll])
Returns a lazy sequence of lists of n items each, at offsets step
apart. If step is not supplied, defaults to n, i.e. the partitions
do not overlap. If a pad collection is supplied, use its elements as
necessary to complete last partition upto n items. In case there are
not enough padding elements, return a partition with less than n items.
无需编写自己的实现.Clojure中提供的分区,这是懒.如果你只使用数字文字,也不需要使用列表:
(partition 2 '(1 2 3 4 5 6))
Run Code Online (Sandbox Code Playgroud)
您可以从您的版本中创建一个延迟序列:
(defn split [n xs]
(lazy-seq
(let [m (take n xs)]
(if (= n (count m))
(cons m (split n (rest xs)))))))
Run Code Online (Sandbox Code Playgroud)
(条件与你的'(if(>(count xs)(dec n))'不同的原因是因为它更有效地计算XS中的M个元素而不是每次都计算整个XS集合(这是一种反对懒惰,因为我们不想走整个集合)
想象一下,每次迭代计算怪异范围内的元素会是什么样的:)
(take 10 (split 2 (range 100000000000)))
=> ((0 1) (1 2) (2 3)...)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1069 次 |
最近记录: |