Most concise way to combine sequence elements

2020-02-11 04:24发布

问题:

Say we have two sequences and we and we want to combine them using some method

val a = Vector(1,2,3)
val b = Vector(4,5,6)

for example addition could be

val c = a zip b map { i => i._1 + i._2 }

or

val c = a zip b map { case (i, j) => i + j }

The repetition in the second part makes me think this should be possible in a single operation. I can't see any built-in method for this. I suppose what I really want is a zip method that skips the creation and extraction of tuples.

Is there a prettier / more concise way in plain Scala, or maybe with Scalaz? If not, how would you write such a method and pimp it onto sequences so I could write something like

val c = a zipmap b (_+_)

回答1:

There is

(a,b).zipped.map(_ + _)

which is probably close enough to what you want to not bother with an extension. (You can't use it point-free, unfortunately, since the implicits on zipped don't like that.)



回答2:

Rex's answer is certainly the easier way out for most cases. However, zipped is more limited than zip, so you might stumble upon cases where it won't work.

For those cases, you might try this:

val c = a zip b map (Function tupled (_+_))

Or, alternatively, if you do have a function or method that does what you want, you have this option as well:

def sumFunction = (a: Int, b: Int) => a + b
def sumMethod(a: Int, b: Int) = a + b

val c1 = a zip b map sumFunction.tupled
val c2 = a zip b map (sumMethod _).tupled

Using .tupled won't work in the first case because Scala won't be able to infer the type of the function.