例如,我有一个列表(1 2 3 4 5 6 7 8 9 10 11)
,并希望将其粗体化为3个元素(或另一个长度)以获得((1 2 3) (4 5 6) (7 8 9) (10 11))
。我可以使用什么漂亮的代码呢?感谢。
答案 0 :(得分:15)
List(1,2,3,4,5,6,7,8,9,10,11) grouped 3 toList
res0: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6),
List(7, 8, 9), List(10, 11))
答案 1 :(得分:15)
因为你也使用Clojure标签......
在Clojure 1.2中有一个内置函数可以在clojure.contrib.seq-utils中的1.1中使用。
(partition-all 3 [1 2 3 4 5 6 7 8 9 10 11])
; => ((1 2 3) (4 5 6) (7 8 9) (10 11))
另请参阅partition
和partition-by
。另请注意,如果您需要稍微不同的内容,partition
和partition-all
会接受一些可选参数,请参阅例如在REPL (doc partition)
。
答案 2 :(得分:3)
在Scala 2.8中,列表混合在IterableLike中,它具有返回Iterator [List [T]]的分组方法,而Iterator又可以转换为List [List [T]]。
List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11).grouped(3).toList
res3: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9), List(10, 11))
如果你想在List上使用粗糙方法,你可以使用隐式转换,例如:
scala> class RList[T](val l: List[T]) {def roughen(n: Int) = l.grouped(n).toList}
defined class RList
scala> implicit def list2rlist[T](l: List[T]) = new RList(l)
list2rlist: [T](l: List[T])RList[T]
scala> List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) roughen 3
res5: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9), List(10, 11))
答案 3 :(得分:2)
def split[A](list : List[A], n : Int) : List[List[A]] = list match {
case List() => List()
case _ => (list take n) :: split(list drop n, n)
}
答案 4 :(得分:2)
另一个clojure版本,用更惯用的clojure编写。
(defn roughen
[n coll]
(lazy-seq
(when-let [s (seq coll)]
(let [[l r] (split-at n s)]
(cons l (roughen n r))))))
注意,split-at
遍历输入序列两次。因此,您可以使用以下内容替换标准版本:
(defn split-at
[n coll]
(loop [n n, s coll, l []]
(if-not (zero? n)
(if-let [s (seq s)]
(recur (dec n) (rest s) (conj l (first s)))
[l nil])
[l s])))
(当然,如上所述,我会使用partition
和朋友。)
答案 5 :(得分:1)
这是我能想到的最好的:
def roughen(l:List[_],s:Int):List[_] ={
if (l.isEmpty) return Nil
val l2 = l.splitAt(s)
l2._1 :: roughen(l2._2,s)
}
val l = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
roughen(l,3)
//returns: List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9), List(10))
答案 6 :(得分:1)
这是与roughen的Clojure 1.0兼容的实现:
(defn roughen
"Roughen sequence s by sub-grouping every n elements.
e.gn (roughen '(a b c d) 2) -> ((a b) (c d))"
[s n]
(loop [result () s s]
(cond (empty? s)
result
(< (count s) n)
(concat result (list s))
:default
(recur (concat result (list (take n s))) (drop n s)))))
user=> (roughen '(a b c d e f g) 2)
((a b) (c d) (e f) (g))
user=> (roughen '(a b c d e f) 2)
((a b) (c d) (e f))
user=> (roughen '(a b c d e f) 4)
((a b c d) (e f))
user=>