Folding e redução
foldLeft e reduce.
Folding e redução é uma aula grátis de Scala for Backend Engineering & Functional Programming no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Scala for Backend Engineering & Functional Programming, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.
Combinando elementos em um só
Às vezes, você precisa combinar todos os elementos de uma coleção em um único valor, como uma soma ou concatenação. Scala oferece fold, foldLeft, foldRight e reduce para isso.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
println(nums.sum)
println(nums.product)
}
}reduce: combinando sem uma semente
reduce combina elementos aos pares usando uma função binária. Ele precisa de pelo menos um elemento; caso contrário, lança uma exceção.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val total = nums.reduce((a, b) => a + b)
println(total)
val max = nums.reduce((a, b) => if (a > b) a else b)
println(max)
}
}foldLeft: combinando com uma semente
foldLeft recebe um valor de semente inicial e uma função. Ele é seguro em coleções vazias (retorna a semente) e permite que o tipo do resultado seja diferente do tipo dos elementos.
Sintaxe: xs.foldLeft(seed)((acc, x) => ...).
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val sum = nums.foldLeft(0)((acc, x) => acc + x)
println(sum)
val empty = List.empty[Int].foldLeft(0)(_ + _)
println(empty)
}
}O padrão do acumulador
Em um fold, o primeiro argumento é o acumulador que carrega o resultado em andamento, e o segundo é o elemento atual. Cada etapa atualiza o acumulador.
object Main {
def main(args: Array[String]): Unit = {
val words = List("Scala", "is", "great")
val sentence = words.foldLeft("")((acc, w) => acc + w + " ")
println(sentence.trim)
}
}O tipo do resultado pode ser diferente
Uma característica poderosa de foldLeft: o tipo do acumulador pode ser diferente do tipo dos elementos. Aqui, dobramos uma lista de números em uma String.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3)
val joined = nums.foldLeft("nums:")((acc, n) => acc + " " + n)
println(joined)
}
}foldRight: da direita
foldRight processa os elementos da direita para a esquerda. O acumulador é o segundo argumento: (x, acc) => .... A direção é importante para operações não comutativas.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val left = nums.foldLeft("")((acc, x) => acc + x)
val right = nums.foldRight("")((x, acc) => acc + x)
println("foldLeft: " + left)
println("foldRight: " + right)
}
}Esquerda versus direita e desempenho
foldLeft é recursivo em cauda e não causa estouro da pilha em listas grandes. foldRight em uma List pode causar estouro da pilha para entradas muito grandes. Prefira foldLeft, a menos que a ordem exija o contrário.
object Main {
def main(args: Array[String]): Unit = {
val big = (1 to 100000).toList
val total = big.foldLeft(0L)((acc, x) => acc + x)
println(total)
}
}Construindo uma coleção com fold
As dobras são suficientemente gerais para construir coleções. Aqui, invertemos uma lista adicionando cada elemento no início de uma lista acumuladora.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val reversed = nums.foldLeft(List.empty[Int])((acc, x) => x :: acc)
println(reversed)
}
}reduceOption para maior segurança
Como reduce falha em coleções vazias, reduceOption retorna um Option: Some(result) quando não está vazio e None quando está vazio.
object Main {
def main(args: Array[String]): Unit = {
println(List(3, 1, 4).reduceOption(_ + _))
println(List.empty[Int].reduceOption(_ + _))
}
}fold: uma variante simétrica
fold é semelhante a foldLeft, mas o acumulador deve ser do mesmo tipo que os elementos. Ele é frequentemente usado com coleções paralelas.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val total = nums.fold(0)(_ + _)
println(total)
}
}Contando com foldLeft
As dobras podem calcular resultados mais elaborados, como contar quantos elementos satisfazem uma condição, tudo em uma única passagem.
object Main {
def main(args: Array[String]): Unit = {
val nums = List(4, 7, 2, 9, 6, 1)
val evenCount = nums.foldLeft(0)((acc, x) => if (x % 2 == 0) acc + 1 else acc)
println(s"even numbers: $evenCount")
}
}Verificação rápida
Qual é a principal diferença entre reduce e foldLeft?
Recapitulação
Você aprendeu sobre dobras e reduções:
reduce— combina elementos aos pares, sem valor inicial, e falha se estiver vazioreduceOption— variante segura que retornaOptionfoldLeft— valor inicial + acumulador, seguro para a pilha, com tipo de resultado flexívelfoldRight— da direita para a esquerda; atenção à pilha em listas grandes- As dobras também podem construir novas coleções
Aprenda Scala com um tutor de IA — grátis
Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.
- Cursos
- 39
- Aulas
- 143
Perguntas Frequentes
A aula “Folding e redução” é grátis?
Sim — o texto completo de “Folding e redução” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Scala for Backend Engineering & Functional Programming, atualize para CoddyKit PRO. O curso de Scala for Backend Engineering & Functional Programming inclui 4 aulas no total.
O que vou aprender em “Folding e redução”?
foldLeft e reduce. Você pratica Scala for Backend Engineering & Functional Programming com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar Scala for Backend Engineering & Functional Programming?
Nenhuma experiência prévia é necessária. Scala for Backend Engineering & Functional Programming no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.
Quanto tempo leva a aula “Folding e redução”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de Scala for Backend Engineering & Functional Programming?
Sim. Cada aula de Scala for Backend Engineering & Functional Programming inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- List, Vector, Set, Map
- Transformações
- Folding e redução
- Agrupamento e ordenação