4

I have following lists -

val A = List(("A","B","C","D"),("A1","B1","C1","D1"),("A2","B2","C2","D2"))

and

val B = List(("P","Q","R","S","T"),("P1","Q1","R1","S1","T1"),("P2","Q2","R2","S2","T2"),("P3","Q3","R3","S3","T3"))

I want to merge 1st element of list A with first element of list B and so on. here list A have 3 elements and B have 4. I want to consider number of elements in list A while merging.

output as below

val combineList = List(("A","B","C","D","P","Q","R","S","T"),("A1","B1","C1","D1","P1","Q1","R1","S1","T1"),
        ("A2","B2","C2","D2","P2","Q2","R2","S2","T2"))
5
  • possible duplicate of stackoverflow.com/questions/7621705/… Commented Jan 9, 2015 at 11:17
  • Using tuples is mandatory? Commented Jan 9, 2015 at 11:20
  • @SergeyLagutin yes. Commented Jan 9, 2015 at 11:22
  • 1
    @Rickard - This is different from that one you have pointed Commented Jan 9, 2015 at 11:24
  • 1
    Possible duplicate of Combining two lists in scala Commented Apr 16, 2017 at 15:17

3 Answers 3

7

If you can use shapeless, then you can simply do

scala> import shapeless.syntax.std.tuple._
scala> A.zip(B).map{case(a,b) => a ++ b}
res1: List[(String, String, String, String, String, String, String, String, String)] = List((A,B,C,D,P,Q,R,S,T), (A1,B1,C1,D1,P1,Q1,R1,S1,T1), (A2,B2,C2,D2,P2,Q2,R2,S2,T2))

It will work on arbitrary size of tuples.

Sign up to request clarification or add additional context in comments.

3 Comments

Sorry. As I understand you mean shapeless library (github.com/milessabin/shapeless/wiki/…).
is there a non-shapeless way to answer the OP's question for arbritrary tuples?
@KevinMeredith - There is not an easy way. Scala does not provide a built in method to add or remove an element from a Tuple(A list is a more appropriate data structure for that while maintaining type safety). A non shapeless way will include first calculating size of the two tuples to determine what will be the -arity of the Tuple(the easiest part) After that create a tuple by calling the appropriate Tuple class(Tuple2, Tuple6 etc) and feed the values programatically.
1
A.zip(B).map { case ((a,b,c,d), (p,q,r,s,t)) => (a,b,c,d,p,q,r,s,t) }

2 Comments

Will this work for tuples with different sizes i.e, if tuples are of size 5 and 6 or 2 and 4 ?
Different tuples are different types, so, no. You'd have to write a different function for that ... or use shapeless, like @mohit suggested in his answer, although, that would not be my advice.
-1

First zip tuples in sequnces:

val lists = for {i <- 0 until A.length
     a = A(i)
     b = B(i)
} yield (a.productIterator ++ b.productIterator).toList

Next define converter from Seq back to Product:

def toTuple(seq: Seq[_]): Product = {
  val clz = Class.forName("scala.Tuple" + seq.size)
  clz.getConstructors()(0).newInstance(seq.map(_.asInstanceOf[AnyRef]): _*).asInstanceOf[Product]
}

And finally do map:

lists.map(toTuple)

This code does not consider different arity of input lists and tuple size's limitation.

3 Comments

This results in List[Product], not List[(String,String,String,String,String,String,String,String,String)]
@Dima This code is about tuples of variadic length. And your comment is about tuples of fixed arity.
Huh? Where do you see anything about "variadic length" in the question? In general tuple means fixed arity. There is a different name for "tuples of variafic length": they are called lists :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.