2017-01-30 1 views
2

Donc, je lis la « Programmation fonctionnelle à Scala » et je fais l'exercice 2.2Comment le travail de && dans un scala foldleft

Mettre en œuvre IsSorted, qui vérifie si un tableau [A] est triée selon une fonction de comparaison suivant: def IsSorted [a] (comme: Array [a], commandé: (a, a) => Boolean): Boolean = {

Ma solution, qui fonctionne

{ 
    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 
    } 
} 

Était assez fier de mon premier départ, mais pensé il ne semble pas très fonctionnel, donc je demande à un ami et il est revenu avec

{ 
    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) 
    } 
} 

Comme wtf, comment cette magie noire possible. Je comprends tout de as.sliding (2,1) .foldLeft (vrai) ((res, a) => commandé (un (0), un (1)), mais le & & respart, je ne peux pas voir à trouver toute la documentation à ce sujet. Je sais qu'il plie le résultat de l'opération précédente, mais comment ça marche, quelle est cette opération appelée.

+1

'' && est l'opérateur logique AND. Il combine le résultat précédent avec la valeur suivante de la séquence, par ex. 'true && false' – Eric

+0

Rien de spécifique à propos de' foldLeft' il ya – cchantep

Répondre

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) 
    } 

&& est un opérateur logique normale ici. la signature de la fonction commandée est (A,A) => Boolean ce qui signifie qu'il faut deux paramètres de type A et true un booléen indiquant si l'argument 1 est supérieur ou inférieur à argument 2. res est accumulateur pour la fonction foldLeft qui est définie sur false même si l'un des éléments n'est pas dans l'ordre de tri approprié. est assuré par le deuxième paramètre au curry 012 La logique simple ici est que, si les éléments adjacents dans la liste sont triés et que tous les éléments précédents de la liste sont également triés, la liste est triée jusqu'à la position actuelle. donc si nous déplaçons cette position actuelle à la fin de la liste et si la liste est encore triée alors la liste entière est triée. Mais même si un élément n'est pas trié par rapport à son voisin adjacent, alors acc est défini sur false et la sortie de la méthode globale sera fausse.

La définition de l'API de la méthode foldLeft est disponible here

+0

Une des difficultés que je rencontre est; il semble que ordonné prend 2 variables, a (0) et un autre (1) + booléen) ce qui n'est pas le cas. Comment scala sait-il que c'est un amalgame de résultats? –

+0

@PeterLai ordonné (a (0), a (1)) renvoie un booléen, Ce booléen est alors associé avec res, un autre booléen. Le résultat de cette expression est le retour de la fonction et devient la res de l'itération suivante. – puhlen

+0

ordonné est juste une fonction de premier ordre qui prend deux paramètres de type A (le type de la liste à vérifier) ​​et le renvoie un booléen. Le contrat ici est que cette fonction doit vérifier la valeur des paramètres passés et doit renvoyer l'indicateur booléen approprié pour indiquer si les deux valeurs sont plus petites ou plus grandes les unes que les autres. –