简体   繁体   中英

I want to merge a Seq[Tuple2] and a Seq[String] to a Seq[Tuple3] in Scala

Here is my solution, but I don't like it very much:

var seq1: Seq[String] = Seq("apple", "banana", "camel")
var seq2: Seq[(String, String)] = Seq( "green" -> "fruit", "yellow" -> "fruit", "brown" -> "animal" )
var iter = seq1.toIterator

seq2.map {s => (s._1, s._2, iter.next()) }

If you find yourself doing much of this kind of thing, the Shapeless library provides some really nice ways to work with tuples without giving up type safety.

For example, you could write the following using Shapeless's prepend operator for tuples ( +: ) and the standard library's zipped , which lets you avoid the creation of intermediate collections:

(seq1, seq2).zipped.map(_ +: _)

This is beautiful, type-safe, and for large collections it'll be more performant than solutions using zip .

You could of course also use zipped without Shapeless:

(seq1, seq2).zipped.map { case (a, (b, c)) => (a, b, c) }

Or:

(seq1, seq2).zipped.map((a, b) => (a, b._1, b._2))

In addition to the fact that this doesn't build an intermediate collection of tuples, the fact that map here takes a function of two arguments (instead of a function from tuples) can sometimes make the syntax a little cleaner (as you can see in the +: example above).

Simple:

scala> var seq1 = Seq("apple", "banana", "camel")
seq1: Seq[String] = List(apple, banana, camel)

scala> var seq2 = Seq("green" -> "fruit", "yellow" -> "fruit", "brown" -> "animal")
seq2: Seq[(String, String)] = List((green,fruit), (yellow,fruit), (brown,animal))

scala> seq1 zip seq2 map { case (s1, (s2, s3)) => (s1, s2, s3) }
res1: Seq[(String, String, String)] = List((apple,green,fruit), (banana,yellow,fruit), (camel,brown,animal))

要么:

seq2 zip seq1 map (x => (x._1._1, x._1._2, x._2))

using product-collections

seq2 flatZip seq1
res0: org.catch22.collections.immutable.CollSeq3[String,String,String] = 
CollSeq((green,fruit,apple),
        (yellow,fruit,banana),
        (brown,animal,camel))

A CollSeq3 is a collection that holds only Tuple3[A,B,C]s and is itself a Tuple3[Seq[A],Seq[B],Seq[C]].

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM