我有一个生成器,它生成不同长度的数字序列。对于序列中的特定值,我想生成一个新序列,该序列在此特定值的右侧和左侧最多具有10
个元素。我尝试了以下但是它无法正常工作:
xs.dropRight(xs.size - xs.indexOf(x) - 10).take(xs.size - xs.indexOf(x) + 10)
一些例子:
Vector(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)
x = 11
Vector(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)
x = 9
Vector(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)
x = 1
Vector(1,2,3,4,5,6,7,8,9,10,11)
x = 18
Vector(8,9,10,11,12,13,14,15,16,17,18,19)
答案 0 :(得分:5)
尝试选择元素间隔的方法slice
:
def myFun[T](value: T, xs: Seq[T], padding: Int) = {
val idx = xs.indexOf(value)
// padding + 1 because slice uses an exclusive upperbound
xs.slice(idx - padding, idx + padding + 1)
}
scala> myFun(3, 0 to 50, 10)
res2: Seq[Int] = Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)
scala> myFun(10, 0 to 50, 10)
res3: Seq[Int] = Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
答案 1 :(得分:1)
你只是把数学做错了。让我们画出各种情况的图片
.......0987654321x123 <-- ending short
321x1234567890....... <-- beginning short
.......0987654321x1234567890....... <-- lots of room
^--- you want this one
val index = xs.indexOf(x)
现在,我们希望之前删除超过十个元素的所有内容。 Drop会忽略负面元素,因此如果开头很短则无关紧要,我们可以drop(index - 10)
。现在我们的照片是
0987654321x123 <-- beginning clipped, end short
321x1234567890....... <-- beginning short
0987654321x1234567890....... <-- beginning clipped, end long
现在我们x
的位置可能已经改变(如果我们放弃了任何东西)。如果没有,我们只需在index
之后取10。如果是这样,我们需要21 - 我们保留的所有10个,加上x
,再加上10个。 (如果没有多少人离开,take
并不关心。)
xs.drop(index - 10).take(if (index > 10) 21 else index + 10)
我们现在已经结束了。
您可以使用slice
来简化数学运算,它使用开始和结束索引。但是,没有固有的理由为什么下降/采取不起作用;你需要仔细计算。特别是,如果您在xs
take
中找到了indexOf(x)
而未在您创建的新内容中{{1}},那么您的解决方案就会有效。 (浪费时间再次寻找它而不是使用数学,但它确实有效。)