和&&在折叠式scala中工作

时间:2017-01-30 18:41:53

标签: scala

所以我正在阅读Scala中的"功能编程"我正在做运动2.2

实现isSorted,它检查是否根据给定的比较函数对Array [A]进行排序: def isSorted [A](as:Array [A],ordered:(A,A)=> Boolean):Boolean = {

我的解决方案,有效

{
  def orderByValue(a : Int, b : Int): Boolean ={
    println (a + " " + b )
    if( a<= b) true
    else false
  }

  //exercise, def to check wheter an Array[a] is sorted
  def isSorted[A] (as: Array[A], ordered: (A,A) => Boolean) : Boolean = {
    var result = true;
    def loop(n: Int) {
      if (result == false)
        false //Return false on first instance
      else if (n < as.length -1) {
        result = ordered(as(n), as(n + 1))
        loop(n + 1)
      }
      else
        result
    }
    loop(0)
    result
  }
}

我第一次感到自豪,但认为它看起来不太实用,所以我问了一位朋友,他回来了

{
  def isSorted2[A] (as: Array[A], ordered: (A,A) => Boolean) : Boolean = {
    as.sliding(2,1).foldLeft(true)((res, a ) => ordered(a(0), a(1)) && res)
  }
}
像wtf一样,这个黑魔法怎么可能。我理解as.sliding(2,1).foldLeft(true)((res,a)=&gt; ordered(a(0),a(1)),但&amp;&amp; respart,我可以&# 39;看看有关它的任何文档。我知道它折叠了前一个操作的结果,但是它是如何工作的,这个操作调用的是什么。

1 个答案:

答案 0 :(得分:4)

def isSorted2[A] (as: Array[A], ordered: (A,A) => Boolean) : Boolean = {
    as.sliding(2,1).foldLeft(true)((res, a ) => ordered(a(0), a(1)) && res)
  }

&&在这里是一个普通的逻辑运算符。有序函数的签名是(A,A) => Boolean,这意味着它需要两个类型为A的参数,而true为一个布尔值,表示参数1是大于还是小于argument2。 res是foldLeft函数的累加器,即使其中一个项目的排序顺序不正确,也设置为false。这由第二个curried参数确保 (res, a ) => ordered(a(0), a(1)) && res

所以这里的简单逻辑是,如果列表中的当前相邻项目已经排序并且列表中的所有先前项目也被排序,则列表将被排序直到当前位置。因此,如果我们将此当前位置移动到列表的末尾,并且如果列表仍然排序,那么整个列表将被排序。但即使一个项目与其相邻邻居相比没有排序顺序,也不会将acc设置为false,并且整个方法的输出将为false。

foldLeft方法的API定义可用here