Scala:如何将foldLeft与通用数组一起使用?

时间:2016-01-23 06:19:37

标签: arrays scala generics foldleft

我有这种方法:

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的实际类型。

3 个答案:

答案 0 :(得分:1)

对于foldLeft的初始值,您可以使用输入数组的头部。但是,foldLeft不是检查数组是否排序的好选择,因为你应该在找到第一个未排序的元素时终止方法但foldLeft将遍历整个数组

修改

我会使用zip和tail的组合并存在:

isSorted(...) = 
   if (as.isEmpty) true
   else !as.zip(as.tail).exists { case (a,b) => !ordered(a,b)}

答案 1 :(得分:1)

我认为你所做的事情可以简化。

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)

答案 2 :(得分:1)

添加到其他答案,您可能不希望迭代整个数组,而是在找到无序对时终止。那么,这个怎么样?

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