在Scala中,检查数组是否是单调的功能性方法是什么?

时间:2016-09-06 06:28:26

标签: scala

我有一个数组val x : Array[Double],并希望检查函数的前提条件,即所有x(i) <= x(i+1)的每个i。在Scala中使用函数式编程的方法是什么?我寻找例如foldLeftfoldRight但他们会累积而不是访问每对相邻元素。

4 个答案:

答案 0 :(得分:5)

考虑一下:

def isMonotonic(arr:Array[Int]) = 
   if (arr.isEmpty) true
   else (arr, arr.tail).zipped.forall {case (a,b) => a <= b}

简化解决方案(感谢@ som-snytt):

def isMonotonic(arr:Array[Int]) = 
   (arr, arr.drop(1)).zipped.forall (_ <= _)

答案 1 :(得分:4)

您可以使用IterableLike.sliding

val isMonotonic = 
  Seq(1,2,3,4,5).sliding(2).forall {
    case Seq(x, y) => x < y
    case _ => true
  }

编辑:

由于您使用的是Array[Double],因此您需要:

val isMonotonic = 
  Array(1d, 2d, 3d, 4d, 5d).sliding(2).forall {
    case Array(x, y) => x < y
    case _ => true
  }

答案 2 :(得分:1)

有几个很好的答案可供选择,接下来的问题是:我们可以将它变成通用的吗?

这是我拍摄的。

def isMonotonic[T](ts: Traversable[T])(implicit ev: Ordering[T]): Boolean = {
  if (ts.size < 2) true
  else if (ev.gt(ts.head, ts.tail.head)) false
  else isMonotonic(ts.tail)
}

似乎适合以下情况。

isMonotonic(Array('c','a','z'))             // false
isMonotonic(Vector(3.1, 2.2, 7.7))          // false
isMonotonic(List[Int]())                    // true
isMonotonic(Seq("abc", "bcb", "tz", "xs"))  // true

答案 3 :(得分:1)

略有不同的方法

def isMonotonic(xs:List[Int]) = xs.sliding(2)
                                  .collectFirst{case List(x,y) if x > y => 1}
                                  .isEmpty

适用于空列表和长度列表,因为从不在那些列表中定义部分函数。因为它是collectFirst,所以它首先证明它不是单调的,如果愿意可以使用xs zip xs.drop(1)想法