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