क्या मैं स्काला में एक साथ दो से अधिक सूचियों को ज़िप कर सकता हूं?


92

निम्नलिखित स्केल सूची को देखते हुए:

val l = List(List("a1", "b1", "c1"), List("a2", "b2", "c2"), List("a3", "b3", "c3"))

मुझे कैसे मिल सकता हैं:

List(("a1", "a2", "a3"), ("b1", "b2", "b3"), ("c1", "c2", "c3"))

चूंकि ज़िप का उपयोग केवल दो सूचियों के संयोजन के लिए किया जा सकता है, मुझे लगता है कि आपको किसी भी तरह मुख्य सूची को पुनरावृत्त करना / कम करना होगा। आश्चर्य नहीं, निम्नलिखित काम नहीं करता है:

scala> l reduceLeft ((a, b) => a zip b)
<console>:6: error: type mismatch;
 found   : List[(String, String)]
 required: List[String]
       l reduceLeft ((a, b) => a zip b)

किसी भी एक सुझाव यह कैसे करना है? मुझे लगता है कि मैं इसे करने के लिए एक बहुत ही सरल तरीका याद कर रहा हूं।

अपडेट: मैं एक ऐसे समाधान की तलाश कर रहा हूं, जिसमें प्रत्येक तत्वों के साथ N सूचियों की सूची ले सकते हैं और M TupleNs की सूची बना सकते हैं।

अद्यतन 2: जैसा कि यह पता चला है कि मेरे विशिष्ट उपयोग-मामले के लिए सूचियों की सूची बेहतर है, बजाय टुपल्स की सूची के, इसलिए मैं कद्दू की प्रतिक्रिया को स्वीकार कर रहा हूं। यह सबसे सरल भी है, क्योंकि यह एक देशी विधि का उपयोग करता है।



निश्चित रूप से ध्यान देने योग्य: stackoverflow.com/questions/1683312/…
वेंकट सुधीर रेड्डी एडेडमा

@VenkatSudheerReddyAedama भी मेरे द्वारा, पांच दिन बाद पूछा गया। ;-)
pr1001

जवाबों:


36

मुझे विश्वास नहीं है कि मनमाने आकार के ट्यूल की सूची तैयार करना संभव है, लेकिन ट्रांज़ोज़ फ़ंक्शन ठीक वही करता है , जिसकी आपको आवश्यकता होती है यदि आपको इसके बजाय सूचियों की सूची प्राप्त करने में कोई आपत्ति न हो।


धन्यवाद, यह पूरी तरह से काम करता है! जैसा कि मैं अपने विशिष्ट उपयोग के मामले में जाता हूं, मैं देखता हूं कि सूचियों की एक सूची वैसे भी बेहतर होगी, क्योंकि मुझे विभिन्न उप-सूचियों को मैप करने और कम करने की आवश्यकता है।
100 बजे pr1001

2
@JoshCason "दो से अधिक" के सबसे संकीर्ण अर्थों में, निश्चित रूप से। तीन वास्तव में दो से अधिक है। मैंने "दो से अधिक" के व्यापक अर्थों में प्रश्न की व्याख्या की, जिसका अर्थ है मनमाने ढंग से कई। और उस मामले में, जब तक आप HListएस और इस तरह तक नहीं पहुंच जाते, तब तक यह करना संभव नहीं है ।
मैथुन

उत्तर में लिंक टूटा हुआ है, नया लिंक scala-lang.org/api/2.12.1/scala/… है
रमेश

213
scala> (List(1,2,3),List(4,5,6),List(7,8,9)).zipped.toList
res0: List[(Int, Int, Int)] = List((1,4,7), (2,5,8), (3,6,9))

आगामी संदर्भ के लिए।


32
यह तीन सूचियों को जिप करने के लिए बहुत अच्छा है। शर्म करो यह तीन से अधिक सूची के लिए काम नहीं करता है :(
theon

2
ध्यान दें कि यह सबसे पहले एक टपल में होना चाहिए: zippedका कार्य नहीं है List
नथानिएल फोर्ड

6
zippedस्केल 2.13 में पदावनत किया गया है। २.१३ में, करोl1.lazyZip(l2).lazyZip(l3).toList
सेठ टिस्यू

30

तो यह कोड का टुकड़ा ओपी की जरूरतों का जवाब नहीं देगा, और न केवल इसलिए कि यह एक चार साल पुराना धागा है, लेकिन यह शीर्षक प्रश्न का उत्तर देता है, और शायद किसी को यह उपयोगी भी लग सकता है।

3 संग्रह ज़िप करने के लिए:

as zip bs zip cs map { 
  case ((a,b), c) => (a,b,c)
}

4 संग्रह करने के लिए इस तरह दिखता है:as zip bs zip cs zip ds map { case ((a,b),c)} map {case ((a,b),c,d)=>(a,b,c,d)}
जेम्स टोबिन

1
@JamesTobin, u shorten toas zip bs zip cs zip ds map {case (((a,b),c),d)=>(a,b,c,d) }
Keepcoding

भिन्न प्रकार की सूचियों के लिए अच्छा है।
एफपी

11

हाँ, zip3 के साथ ।


2
धन्यवाद, लेकिन यह केवल 3 सूचियों के साथ काम करता है। मैं एक ऐसे समाधान की तलाश कर रहा हूं जो M तत्वों के साथ N सूचियों की सूची ले सके और M TupleNs की सूची बना सके।
pr1001

6

transposeउसने चाल चली। एक संभव एल्गोरिथ्म है:

def combineLists[A](ss:List[A]*) = {
    val sa = ss.reverse;
    (sa.head.map(List(_)) /: sa.tail)(_.zip(_).map(p=>p._2 :: p._1))
}

उदाहरण के लिए:

combineLists(List(1, 2, 3), List(10,20), List(100, 200, 300))
// => List[List[Int]] = List(List(1, 10, 100), List(2, 20, 200))

उत्तर इनपुट में सबसे छोटी सूची के आकार में छोटा है।

combineLists(List(1, 2, 3), List(10,20))
// => List[List[Int]] = List(List(1, 10), List(2, 20))

1
यह जवाब लगभग चाल करता है, हालांकि, यह तत्वों को उलट देता है। क्या आप एक बेहतर संस्करण का सुझाव दे सकते हैं जो अपेक्षित क्रम में आउटपुट का उत्पादन करता है? धन्यवाद
fracca

संशोधित संस्करण जो आदेश को बरकरार रखता है: def combineLists[A](ss:List[A]*) = { val sa = ss.reverse; (sa.head.map(List(_)) /: sa.tail)(_.zip(_).map(p=>p._2 :: p._1)) }
rogermenezes

5

सभी विभिन्न वर्गों के रूप में अपनी अलग टपल आकार के स्काला व्यवहार करता है ( Tuple1, Tuple2, Tuple3, Tuple4, ..., Tuple22), जबकि वे से सभी इनहेरिट करना Productविशेषता पर्याप्त जानकारी ले यह नहीं है कि विशेषता है, वास्तव में tuples के विभिन्न आकारों से डेटा मानों का उपयोग कर यदि वे सभी एक ही कार्य द्वारा वापस किए जा सकते हैं। (और इस मामले को संभालने के लिए स्काला की जेनेरिक पर्याप्त शक्तिशाली नहीं हैं।)

आपकी सबसे अच्छी शर्त सभी 22 टुपल आकारों के लिए जिप फ़ंक्शन के ओवरलोड को लिखना है। एक कोड जनरेटर शायद आपको इसमें मदद करेगा।


5

यदि आप आवेदक स्कैल्प / बिल्लियों / (अपने पसंदीदा कार्यात्मक काम को यहां डालें) मार्ग से नीचे नहीं जाना चाहते हैं, तो पैटर्न मिलान मिलान के लिए रास्ता है, हालांकि (_, _)वाक्यविन्यास घोंसले के साथ थोड़ा अजीब है, इसलिए चलो इसे बदलते हैं:

import scala.{Tuple2 => &}

for (i1 & i2 & i3 & i4 <- list1 zip list2 zip list3 zip list4) yield (i1, i2, i3, i4)

&यहाँ एक मनमाना विकल्प है, कुछ भी है कि अच्छा इन्फ़िक्स यह करना चाहिए लग रहा है। यद्यपि आपको कोड समीक्षा के दौरान कुछ उभरी हुई भौहें मिलेंगी।

यह भी आप कर सकते हैं के साथ काम करना चाहिए zip(जैसे Futures)


5

मेरा मानना ​​है कि यह दोहराव के बिना संभव नहीं है। एक साधारण कारण के लिए: आप जिस प्रकार के फ़ंक्शन के लिए पूछ रहे हैं, उसके प्रकार को परिभाषित नहीं कर सकते।

उदाहरण के लिए, यदि आपका इनपुट था List(List(1,2), List(3,4)), तो रिटर्न प्रकार होगा List[Tuple2[Int]]। यदि इसमें तीन तत्व होते हैं, तो रिटर्न प्रकार होगा List[Tuple3[Int]], और इसी तरह।

आप लौट सकते हैं List[AnyRef], या यहां तक ​​कि List[Product], और फिर मामलों का एक गुच्छा बना सकते हैं , प्रत्येक स्थिति के लिए एक।

सामान्य सूची हस्तांतरण के लिए, यह काम करता है:

def transpose[T](l: List[List[T]]): List[List[T]] = l match {
  case Nil => Nil
  case Nil :: _ => Nil
  case _ => (l map (_.head)) :: transpose(l map (_.tail))
}

यह मनमाने आकार की सूचियों के लिए काम नहीं करेगा। उदाहरण के लिए: स्थानान्तरण (सूची (सूची ("ए", "बी"), सूची ("सी"))
वेंकट सुधीर रेड्डी एडीमा

1
@VenkatSudheerReddyAedama अधूरे मैट्रिसेस का ट्रांसपोज़ेशन मेरे लिए मायने नहीं रखता। अपने उदाहरण लेने के लिए, अगर cसाथ aया साथ में b? और आप इसे दूसरे के अनुरूप होने का प्रतिनिधित्व कैसे करेंगे?
डैनियल सी। सोब्राल

माना। वह अधूरा मैट्रिक्स है। मैं zipAll की तर्ज पर कुछ ढूंढ रहा था। कहो मेरे मामले में, cलाइन में साथ है a(यानी, इन-लाइन सूचकांक के साथ)?
वेंकट सुधीर रेड्डी एडमा


0

स्कलाज़ के साथ:

import scalaz.Zip
import scalaz.std.list._

// Zip 3
Zip[List].ap.tuple3(List("a1", "b1"),
                    List("a2", "b2"),
                    List("a3", "b3"))

// Zip 4
Zip[List].ap.tuple4(List("a1", "b1"),
                    List("a2", "b2"),
                    List("a3", "b3"),
                    List("a4", "b4"))

// Zip 5
Zip[List].ap.tuple5(List("a1", "b1"),
                    List("a2", "b2"),
                    List("a3", "b3"),
                    List("a4", "b4"),
                    List("a5", "b5"))

5 से अधिक के लिए:

// Zip 6
Zip[List].ap.apply6(List("a1", "b1"),
                    List("a2", "b2"),
                    List("a3", "b3"),
                    List("a4", "b4"),
                    List("a5", "b5"),
                    List("a6", "b6"))((_, _, _, _, _, _))

// Zip 7
Zip[List].ap.apply7(List("a1", "b1"),
                    List("a2", "b2"),
                    List("a3", "b3"),
                    List("a4", "b4"),
                    List("a5", "b5"),
                    List("a6", "b6"),
                    List("a7", "b7"))((_, _, _, _, _, _, _))

...

// Zip 12
Zip[List].ap.apply12(List("a1", "b1"),
                     List("a2", "b2"),
                     List("a3", "b3"),
                     List("a4", "b4"),
                     List("a5", "b5"),
                     List("a6", "b6"),
                     List("a7", "b7"),
                     List("a8", "b8"),
                     List("a9", "b9"),
                     List("a10", "b10"),
                     List("a11", "b11"),
                     List("a12", "b12"))((_, _, _, _, _, _, _, _, _, _, _, _))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.