2010-05-20 9 views
6

उदाहरण के लिए, मेरे पास (1 2 3 4 5 6 7 8 9 10 11) की एक सूची है, और ((1 2 3) (4 5 6) (7 8 9) (10 11)) प्राप्त करने के लिए इसे 3 तत्वों (या दूसरी लंबाई) से roughen करना चाहते हैं। इसके लिए मैं किस सुंदर कोड का उपयोग कर सकता हूं? धन्यवाद।एक कार्यात्मक शैली में एक सूची कैसे roughen (flatten के विपरीत)?

+3

शैली के लिए -1। वास्तविक प्रश्न – Dario

+2

"रूगेन" को समझना मुश्किल है? मैं व्यक्तिगत रूप से इसे "समूहीकृत" के रूप में संदर्भित करता हूं, जैसा कि स्कैला करता है। :-) –

उत्तर

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) 
} 
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)) 
+0

+1 अच्छा! ...... – Dario

+0

अच्छा! कोई क्लोजर कोड है? – user342304

3

स्काला 2.8 में, सूची IterableLike जो वर्गीकृत किया विधि है जो देता है एक इटरेटर [सूची [टी]], जो बारी में सूची में [सूची [टी]] परिवर्तित किया जा सकता है में घुलमिल।

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

आप सूची पर एक मोटा हो जाना विधि चाहते हैं तो आप एक अंतर्निहित रूपांतरण का उपयोग कर सकते हैं, कुछ की तरह:

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)) 
+0

ओह, थॉमस के जवाब को नहीं देखा। –

+0

सभी जवाब बहुत अच्छा है! लेकिन समूहीकृत नाम खराब है, रूजन अधिक सामान्य है, जैसे कि फ्लैटन के खिलाफ: पी, हो सकता है कि रूफेन उस कार्य को प्राप्त कर ले, जो इस तरह की लंबाई, रेगेक्स ..., बेहतर होगा – user342304

+0

लेकिन राउगेन कम से कम (मेरे लिए कम से कम) कि सूचियां एक समान लंबाई की तरह नहीं थीं, जैसे कि एक रगड़ सरणी। मुझे लगता है कि विभाजन एक ही ऑपरेशन के लिए अन्य भाषाओं/पुस्तकालयों में प्रयोग किया जाता है। – pdbartlett

1

यह सबसे अच्छा है मैं के साथ आ सकता है आप क्लोजर टैग का भी उपयोग करते हैं ...

क्लोजर 1.2 में ऐसा करने के लिए एक अंतर्निहित फ़ंक्शन है, जो क्लोज़ में 1.1 में भी उपलब्ध है ure.contrib.seq-utils।

(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 कुछ वैकल्पिक तर्क स्वीकार करते हैं यदि आपको कुछ अलग चाहिए, उदाहरण के लिए देखें। आरईपीएल पर (doc partition)

(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=> 
15

के बाद से:

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

मैं क्लोजर के पुस्तकालयों में कार्यक्षमता की चौड़ाई से अक्सर आश्चर्यचकित हूं ... लेकिन इच्छा है कि आप जो जल्दी चाहते हैं उन्हें ढूंढने का एक चालाक तरीका हो! (निश्चित रूप से स्टैक ओवरफ्लो पर सुपरस्टार पूछना हमेशा एक विकल्प है :-)) – mikera

+3

http://clojure.org/cheatsheet देखें - विभाजन "नेस्टेड seqs" में ठीक है। –

1

यहाँ एक Clojure मोटा हो जाना का 1.0 संगत कार्यान्वयन है।

(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 का प्रयोग करेंगे और दोस्तों के रूप में पहले से ही ऊपर उल्लेख किया है)

2

और एक और clojure संस्करण, अधिक मुहावरेदार clojure में लिखा:

संबंधित मुद्दे