scala 在数组中查找索引的功能代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12338787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 04:30:44  来源:igfitidea点击:

Functional code for finding index in array

scalafunctional-programming

提问by Andriy Buday

I would like to refactor this piece of Scalacode in functional style:

我想以函数式的方式重构这段Scala代码:

var k = -1
for (i <- 0 until array.length)
  if ((i < array.length - 1) && array(i) < array(i + 1))
    k = i

Array in Scalahas indexWhere, which can be used for something like val index = array.indexWhere(c => c == 'a'). I'm looking for something similar, which would take into account two sequential elements of array.

Scala中的数组具有indexWhere,可用于诸如val index = array.indexWhere(c => c == 'a'). 我正在寻找类似的东西,它会考虑数组的两个连续元素。

回答by Travis Brown

When you need to look at adjacent elements in a collection, the usual functional approach is to "zip" the collection with its tail. Consider the following simplified example:

当您需要查看集合中的相邻元素时,通常的功能方法是使用其尾部“压缩”集合。考虑以下简化示例:

scala> val xs = List(5, 4, 2, 3, 1)
xs: List[Int] = List(5, 4, 2, 3, 1)

scala> val tail = xs.tail
tail: List[Int] = List(4, 2, 3, 1)

scala> xs.zip(tail)
res0: List[(Int, Int)] = List((5,4), (4,2), (2,3), (3,1)

Now we can use indexWhere:

现在我们可以使用indexWhere

scala> res0.indexWhere { case (x, y) => x < y }
res1: Int = 2

In your case, the following is essentially equivalent to your code:

在您的情况下,以下内容基本上等同于您的代码:

val k = (array zip array.tail) lastIndexWhere { case (x, y) => x < y }

I'm using lastIndexWhereinstead of indexWhere, since in your code you don't stop the loop when you hit a pair for which the predicate holds.

我使用的是lastIndexWhere代替indexWhere,因为在您的代码中,当您命中谓词成立的一对时,您不会停止循环。

回答by Adam Rabung

slidinggives you sliding window into the collection, ie

sliding给你滑动窗口进入集合,即

scala> Array(1,2,2,4,5,6, 6).sliding(2).toList
res12: List[Array[Int]] = List(Array(1, 2), Array(2, 2), Array(2, 4), Array(4, 5), Array(5, 6), Array(6, 6))

So that would make finding the index of the first matching pair easy:

这样就可以轻松找到第一个匹配对的索引:

Array(1,2,2,4,5,6, 6).sliding(2).indexWhere { case Array(x1, x2) => x1 == x2 }

That only gives you the first index, use collectto catch em all!

那只给你第一个索引,collect用来捕获它们!

Array(1,2,2,4,5,6, 6)
  .sliding(2)     //splits each in to pairs
  .zipWithIndex   //attaches the current index to each pair
  .collect { case (Array(x1, x2), index) if (x1 == x2) => index }  //collect filters out non-matching pairs AND transforms them to just the inde