Как избежать вызова 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)