Scala:如何将 foldLeft 与通用数组一起使用?
Scala: How do I use foldLeft with a generic array?
我有这个方法:
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
val sorted = for (it <- as.sliding(2))
yield {
if (it.length == 2) ordered.apply(it(0), it(1))
else true
}
sorted.find(!_).isEmpty
}
我想做的是使用 foldLeft
并应用二元运算符。但是,foldLeft
需要一个初始值,我不知道在不知道 A
.
的真实类型的情况下我可以提供什么初始值
对于 foldLeft 的初始值,您可以使用输入数组的头部。但是 foldLeft 不是检查数组是否排序的好选择,因为当找到第一个未排序的元素时应该终止方法,但 foldLeft 将遍历整个数组
编辑:
我会结合使用 zip 和 tail 并存在:
isSorted(...) =
if (as.isEmpty) true
else !as.zip(as.tail).exists { case (a,b) => !ordered(a,b)}
我认为你所做的可以简化。
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
if (as.size < 2)
true
else
as.sliding(2).find(x => !ordered(x(0),x(1))).isEmpty
}
isSorted: [A](as: Array[A], ordered: (A, A) => Boolean)Boolean
scala> isSorted( Array(2), {(a:Int,b:Int) => a < b} )
res42: Boolean = true
scala> isSorted( Array(2,4), {(a:Int,b:Int) => a < b} )
res43: Boolean = true
scala> isSorted( Array(2,4,5), {(a:Int,b:Int) => a < b} )
res44: Boolean = true
scala> isSorted( Array(2,14,5), {(a:Int,b:Int) => a < b} )
res45: Boolean = false
或者,也许更简洁一点(但不一定更容易理解):
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
if (as.size < 2)
true
else
!as.sliding(2).exists(x => ordered(x(1),x(0)))
}
更新
好的,我想我已经获得了简明奖。
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean =
as.isEmpty || as.init.corresponds(as.tail)(ordered)
除了其他答案之外,您可能不想遍历整个数组,而是在找到无序对时终止。那么,这个怎么样?
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
var sorted = true
val ita = as.sliding(2)
while (sorted && ita.hasNext) {
val it = ita.next
sorted = if (it.size > 1) ordered(it(0), it(1)) else true
}
sorted
}
val a = Array(1, 3, 2, 4, 5)
val b = Array(1, 2, 3, 4, 5)
isSorted[Int](a, _ < _) // returns false
isSorted[Int](b, _ < _) // returns true
我有这个方法:
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
val sorted = for (it <- as.sliding(2))
yield {
if (it.length == 2) ordered.apply(it(0), it(1))
else true
}
sorted.find(!_).isEmpty
}
我想做的是使用 foldLeft
并应用二元运算符。但是,foldLeft
需要一个初始值,我不知道在不知道 A
.
对于 foldLeft 的初始值,您可以使用输入数组的头部。但是 foldLeft 不是检查数组是否排序的好选择,因为当找到第一个未排序的元素时应该终止方法,但 foldLeft 将遍历整个数组
编辑:
我会结合使用 zip 和 tail 并存在:
isSorted(...) =
if (as.isEmpty) true
else !as.zip(as.tail).exists { case (a,b) => !ordered(a,b)}
我认为你所做的可以简化。
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
if (as.size < 2)
true
else
as.sliding(2).find(x => !ordered(x(0),x(1))).isEmpty
}
isSorted: [A](as: Array[A], ordered: (A, A) => Boolean)Boolean
scala> isSorted( Array(2), {(a:Int,b:Int) => a < b} )
res42: Boolean = true
scala> isSorted( Array(2,4), {(a:Int,b:Int) => a < b} )
res43: Boolean = true
scala> isSorted( Array(2,4,5), {(a:Int,b:Int) => a < b} )
res44: Boolean = true
scala> isSorted( Array(2,14,5), {(a:Int,b:Int) => a < b} )
res45: Boolean = false
或者,也许更简洁一点(但不一定更容易理解):
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
if (as.size < 2)
true
else
!as.sliding(2).exists(x => ordered(x(1),x(0)))
}
更新
好的,我想我已经获得了简明奖。
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean =
as.isEmpty || as.init.corresponds(as.tail)(ordered)
除了其他答案之外,您可能不想遍历整个数组,而是在找到无序对时终止。那么,这个怎么样?
def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
var sorted = true
val ita = as.sliding(2)
while (sorted && ita.hasNext) {
val it = ita.next
sorted = if (it.size > 1) ordered(it(0), it(1)) else true
}
sorted
}
val a = Array(1, 3, 2, 4, 5)
val b = Array(1, 2, 3, 4, 5)
isSorted[Int](a, _ < _) // returns false
isSorted[Int](b, _ < _) // returns true