3

このScalaコードを関数型スタイルにリファクタリングしたいと思います。

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

Scalaの配列には がありindexWhere、 のようなものに使用できますval index = array.indexWhere(c => c == 'a')。私は、配列の2つの連続した要素を考慮した、似たようなものを探しています。

4

2 に答える 2

18

コレクション内の隣接する要素を確認する必要がある場合、通常の機能的なアプローチは、コレクションをテールで「zip」することです。次の簡略化された例を考えてみましょう。

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)

今、私たちは使用することができますindexWhere

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

あなたの場合、以下は本質的にあなたのコードと同等です:

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

lastIndexWhereの代わりに使用indexWhereしています。コードでは、述語が保持するペアにヒットしたときにループを停止しないためです。

于 2012-09-09T11:54:49.313 に答える
11

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))

したがって、最初に一致するペアのインデックスを簡単に見つけることができます。

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

それはあなたに最初のインデックスを与えるだけです、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
于 2012-09-09T12:01:29.377 に答える