是否有现有的功能可以移动Range
生成另一个Range
,例如
val r = 1 to 5
val s = r.map(_ + 2) // produces Vector(3, 4, 5, 6, 7)
我想获得3 to 7
。
答案 0 :(得分:5)
以下是我将如何实现它:
implicit class RangeHasShift(val r: Range) extends AnyVal {
def shift(n: Int): Range = {
val start1 = r.start + n
val end1 = r.end + n
// overflow check
if ((n > 0 && (start1 < r.start || end1 < r.end)) ||
(n < 0 && (start1 > r.start || end1 > r.end)))
throw new IllegalArgumentException(s"$r.shift($n) causes number overflow")
if (r.isInclusive)
new Range.Inclusive(start1, end1, r.step)
else
new Range (start1, end1, r.step)
}
}
def check(r: Range) = assert(r == r.shift(123).shift(-123))
check(1 to 10)
check(1 to -1)
check(1 to -1 by -1)
check(1 to 10 by 3)
check(1 until 10)
check(1 until -1)
check(1 until -1 by -1)
check(1 until 10 by 3)
我想知道这是否存在于API的某个地方?
答案 1 :(得分:1)
如果您的主要目标是在移动范围时不在内存中拥有所有值,则可以使用视图:
scala> (1 to 999999999).view.map(_ + 2)
res0: scala.collection.SeqView[Int,Seq[_]] = SeqViewM(...)
这类似于返回懒惰序列的旧的Range实现。
答案 2 :(得分:0)
另一种返回包含范围的简单方法
val newRange = previousRange.start + shift to previousRange.end + shift
或
val newRange = Range.inclusive(previousRange.start + shift, previousRange.end + shift)