2016-02-15 6 views
10

मान लें हम अलग अलग आकार के निम्न सूची है:पिन डिफ़ॉल्ट तत्व के साथ अलग-अलग लंबाई की दो सूचियां को भरने के लिए

val list1 = ("a", "b", "c") 
val list2 = ("x", "y") 

अब मैं इन 2 सूचियों विलय और स्ट्रिंग तत्वों के साथ एक नई सूची बनाने के लिए चाहते हैं concatenated जा रहा है :

val desiredResult = ("ax", "by", "c") 

मैं

val wrongResult = (list1, list2).zipped map (_ + _) 
here प्रस्तावित के रूप में

की कोशिश की, लेकिन यह इरादे के रूप में काम नहीं करता है, क्योंकि ज़िप लंबे सूची के उन तत्वों को त्याग देता है जिन्हें मिलान नहीं किया जा सकता है।

मैं इस समस्या को कैसे हल कर सकता हूं? सूचियों को ज़िप करने का कोई तरीका है और यदि कोई सूची अधिक है तो "डिफ़ॉल्ट तत्व" (इस मामले में खाली स्ट्रिंग की तरह) दें?

उत्तर

26

विधि आप देख रहे हैं .zipAll है:

scala> val list1 = List("a", "b", "c") 
list1: List[String] = List(a, b, c) 

scala> val list2 = List("x", "y") 
list2: List[String] = List(x, y) 

scala> list1.zipAll(list2, "", "") 
res0: List[(String, String)] = List((a,x), (b,y), (c,"")) 

.zipAll 3 तथ्य होते हैं:

  • डिफ़ॉल्ट मान के साथ ज़िप करने

    • iterable अगर this (संग्रह .zipAll पर कॉल किया जाता है) छोटा
    • है
    • डिफ़ॉल्ट मान है, तो अन्य संग्रह है कम
  • +1

    मुझे लगता है कि हमेशा कुछ ऐसा नहीं जानता है। –

    +0

    धन्यवाद! अब यह इस समाधान के साथ काम करता है: 'list1.zipAll (list2, "", "") मानचित्र ({case (y, x) => y + x})' लेकिन 'list1.zipAll (list2," के साथ पहले जैसा नहीं है "," ") मानचित्र (_ + _)'। ज़िप्ड फ़ंक्शन की तरह zipAll के साथ मैं छोटा वाक्यविन्यास क्यों नहीं उपयोग कर सकता? – ForceOfWill

    +1

    @ForceOfWill: '(list1, list2) .zipped' एक 'tuple2Zipped' देता है, जहां [' .map'] (http://www.scala-lang.org/api/current/index.html#scala.runtime .Tuple2Zipped @ मानचित्र [बी, टू] (एफ: (एल 1, एल 2) => बी) (implicitcbf: scala.collection.generic.CanBuildFrom [Repr1, B, To]): करने के लिए) एक f f: (El1, एल 2) => बी' (यानी एक समारोह जो 2 तर्क लेता है)। 'सूची [ए]' ''.map' एक' f: ए => बी' लेता है, यानी केवल 1 तर्क (जो इस मामले में 'tuple2' है)। दुर्भाग्य से इसका मतलब है कि '_ + _' (जो एक फ़ंक्शन है जो 2 तर्क लेता है) यहां लागू नहीं किया जा सकता है। – Marth

    2

    API- आधारित zipAll जाने का रास्ता है, फिर भी इस प्रकार आप उदाहरण के लिए इसे लागू कर सकते हैं (एक व्यायाम के रूप में),

    implicit class OpsSeq[A,B](val xs: Seq[A]) extends AnyVal { 
        def zipAll2(ys: Seq[B], xDefault: A, yDefault: B) = { 
        val xs2 = xs ++ Seq.fill(ys.size-xs.size)(xDefault) 
        val ys2 = ys ++ Seq.fill(xs.size-ys.size)(yDefault) 
        xs2.zip(ys2) 
        } 
    } 
    

    इसलिए उदाहरण के लिए

    Seq(1,2).zipAll2(Seq(3,4,5),10,20) 
    List((1,3), (2,4), (10,5)) 
    

    और

    list1.zipAll2(list2, "", "") 
    List((a,x), (b,y), (c,"")) 
    

    एक पुनरावर्ती संस्करण,

    def zipAll3[A,B](xs: Seq[A], ys: Seq[B], xd: A, yd: B): Seq[(A,B)] = { 
        (xs,ys) match { 
        case (Seq(), Seq()) => Seq() 
        case (x +: xss, Seq()) => (x,yd) +: zipAll3(xss, Seq(), xd, yd) 
        case (Seq(), y +: yss) => (xd,y) +: zipAll3(Seq(), yss, xd, yd) 
        case (x +: xss, y +: yss) => (x,y) +: zipAll3(xss, yss, xd, yd) 
        } 
    } 
    

    डिफ़ॉल्ट xd और डिफ़ॉल्ट yd मूल्यों के साथ।

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