Как избежать вызова toVector на каждом Scala для понимания / выхода?

У меня есть несколько методов, которые работают на Vector последовательности и следующая идиома распространены при объединении данных из нескольких векторов в один с использованием a для понимания / выхода:

(for (i <- 0 until y.length) yield y(i) + 0.5*dy1(i)) toVector

Обратите внимание на закрытие toVector и заключающие в скобки вокруг для понимания. Я хочу избавиться от этого, потому что это уродливо, но удаление его приводит к следующей ошибке:

type mismatch;
 found   : scala.collection.immutable.IndexedSeq[Double]
 required: Vector[Double]

Есть ли лучший способ достижения того, чего я хочу, избегая явного вызова toVector много раз, чтобы по существу достичь неоперации (преобразование и индексированная последовательность... в индексированную последовательность)?

2 ответа

Один из способов избежать кастинга, например toVector, должен вызывать, если возможно, только те методы, которые возвращают один и тот же тип коллекции.

y.zipWithIndex.map{case (yv,idx) => yv + 0.5*dy1(idx)}

for yield на Range который вы используете в своем примере, дает Vector[T] по умолчанию.

пример,

scala> val squares= for (x <- Range(1, 3)) yield x * x
squares: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 4)

проверить тип,

scala> squares.isInstanceOf[Vector[Int]]
res14: Boolean = true

Обратите внимание, что Vector[T] также расширяется IndexedSeq[T],

@SerialVersionUID(-1334388273712300479L)
final class Vector[+A] private[immutable] (private[collection] val startIndex: Int, private[collection] val endIndex: Int, focus: Int)
extends AbstractSeq[A]
   with IndexedSeq[A]
   with GenericTraversableTemplate[A, Vector]
   with IndexedSeqLike[A, Vector[A]]
   with VectorPointer[A @uncheckedVariance]
   with Serializable
   with CustomParallelizable[A, ParVector[A]]

Вот почему приведенный выше результат также является примером IndexedSeq[T],

scala> squares.isInstanceOf[IndexedSeq[Int]]
res15: Boolean = true

Вы можете определить тип вашего результата как IndexedSeq[T] и по-прежнему достичь того, что вы хотите с Vector без явного вызова .toVector

scala> val squares: IndexedSeq[Int] = for (x <- Range(1, 3)) yield x * x
squares: IndexedSeq[Int] = Vector(1, 4)

scala> squares == Vector(1, 4)
res16: Boolean = true

Но для выхода на Seq[T] дает List[T] по умолчанию.

scala> val squares = for (x <- Seq(1, 3)) yield x * x
squares: Seq[Int] = List(1, 9)

Только в том случае, если вы хотите вектор, вы должны .toVector результат.

scala> squares.isInstanceOf[Vector[Int]]
res21: Boolean = false

scala> val squares = (for (x <- Seq(1, 3)) yield x * x).toVector
squares: Vector[Int] = Vector(1, 9)
Другие вопросы по тегам