• Nenhum resultado encontrado

Estrutura de dados funcionais

N/A
N/A
Protected

Academic year: 2021

Share "Estrutura de dados funcionais"

Copied!
38
0
0

Texto

(1)
(2)

Estrutura de dados funcionais

Objetivos da programação funcional:

Código conciso

Reuso de código (tipicamente, funções)

Problema:

Como reduzir a escrita do código e manter a

legibilidade do código de forma

simultânea

?

Problemas com solução imperativa exige mutabilidade

(3)

Estrutura de dados funcionais

Solução do

paradigma

funcional:

Algoritmos que utilizam

operações funcionais a partir de

estrutura de dados funcionais!

(4)

Como escolher as estruturas mais

adequadas?

Em Scala, a decisão recai sobre três aspectos:

O uso de uma função como

predicado

Predicado: função que recebe um ou mais parâmetros e

retorna um booleano

O uso de funções de alta ordem

Objetivo: permitir a

composição

de funções

Uso de loops

implícitos

Métodos das coleções que implementam funções

puras

.

Código conciso e imutável.

(5)
(6)
(7)
(8)

Operações Funcionais

As principais estruturas de dados funcionais de

Scala apresentam um conjunto de operações em

comum:

Traversing

(percorrer a coleção);

Mapping

(transformação de uma coleção em outra

coleção);

Filtering

(extração de uma nova coleção a partir de um

predicado);

Folding

e

Reducing

(redução de uma coleção em uma

coleção menor ou em um valor).

(9)

Operação de Traversing

Objetivo: percorrer todos os elementos de uma

coleção.

Método principal: foreach

O método foreach recebe uma função como

argumento.

A função a ser passada deverá ter apenas um

parâmetro e não deve ter tipo de retorno (ou seja, deve

ser Unit).

O parâmetro da função deverá ser do mesmo tipo dos

elementos da coleção.

(10)

Operação de Traversing

Exemplo 1: imprimir os elementos de uma coleção

Formas concisas do foreach:

val x = List(1, 2, 3) // Ou Array, Set, Map, etc

x.foreach((i: Int) => println(i)) // imprime os elementos

x.foreach(i => println(i)) // por inferência

x.foreach(println(_)) // aplicação parcial da função x.foreach(println) // forma mais concisa da função

(11)

Operação de Traversing

Exemplo 2: percorrendo os caracteres de uma

String

"Teste".foreach(c => println(c))

(12)

Operação de Traversing

Exemplo 3: Atribuição e iteração simultânea

(13)

Operação de Traversing

Exemplo 4: percorrendo os elementos de um Map

val avaliacao = Map("Slayer" -> 10.0, "Metallica" -> 9.5, "Wesley Safadão" -> -1.0)

// usando o for tradicional

(14)

Operação de Traversing

Exemplo 4: percorrendo os elementos de um Map

val avaliacao = Map("Slayer" -> 10.0, "Metallica" -> 9.5, "Wesley Safadão" -> -1.0)

// usando o foreach e o case avaliacao.foreach {

case(artista, nota) => println(s"artista: $artista, nota: $nota")

(15)

Operação de Traversing

Exemplo 4: percorrendo os elementos de um Map

val avaliacao = Map("Slayer" -> 10.0, "Metallica" -> 9.5, "Wesley Safadão" -> -1.0)

// usando o foreach diretamente

avaliacao.foreach(x => println(s"artista: ${x._1}, nota: ${x._2}"))

(16)

Operação de Traversing

Exemplo 5: percorrendo as chaves e valores do Map

val avaliacao = Map("Slayer" -> 10.0, "Metallica" -> 9.5, "Wesley Safadão" -> -1.0)

// percorrendo as chaves

avaliacao.keys.foreach(println)

// percorrendo os valores

(17)

Operação de Mapping

Objetivo: transformar uma coleção em outra

aplicando um algoritmo para cada elemento da

coleção original.

Método principal: map

O método map recebe uma função como argumento.

Não confundir com a coleção Map!

O tipo dos elementos da nova coleção depende do tipo

de retorno da função passada como parâmetro do

(18)

Operação de Mapping

Exemplo 1: Converte uma String para maiúsculo

val nomes = Array("João", "José", "Maria")

val nomesMaiusculo = nomes.map(e => e.toUpperCase)

// forma concisa

(19)

Operação de Mapping

Exemplo 2: array com o tamanho das strings

val nomes = Array("João", "José", "Maria") val tamanhoNomes = nomes.map(_.length)

(20)

Operação de Mapping

Exemplo 3: Contando as ocorrências de caracteres

de uma String

val s = "abacate"

val ocorrencias = s map(x => s.count(_ == x))

// Obtendo resultados únicos com o método distinct s.distinct.map(x => (x, s.count(_ == x)))

// Mesmo resultado com o método groupBy

s.groupBy(c => c).map(e => (e._1, e._2.length))

// Idem, sem a função anônima do groupBy

s.groupBy(identity).map(e => (e._1, e._2.length))

(21)

Outras operações de Mapping

Operação de Mapping

Nome Exemplo Descrição

collect List(0, 1, 0) collect {case 0 =>"ok"}

Transforma cada elemento usando uma função parcial, mantendo apenas os

elementos que satisfazem a função.

flatMap List("chá,café") flatMap (_.split(','))

Transforma cada elemento usando uma função,

retornando uma única lista com os elementos

(22)

Operação de Filtering

Objetivo: filtrar os elementos de uma coleção

para criar uma nova coleção que atende a uma

condição .

Método principal: filter

O método filter requer que o predicado possua um

parâmetro do mesmo tipo dos elementos da coleção.

Se a condição lógica do predicado for atendida (true),

o elemento é “filtrado” e inserido na coleção de

retorno.

(23)

Operação de Filtering

Exemplo 1: Criando uma lista com números pares

val x = List.range(1, 10) // 1, 2, ..., 9

(24)

Operação de Filtering

Exemplo 2: Extraindo elementos de uma String

val nomes = Set("Ana", "José", "João", "Maria")

val x = nomes.filter(_.startsWith("J")) // José, João val y = nomes.filter(_.length > 4) // Maria

(25)

Operação de Filtering

Exemplo 3: Criando um novo Map a partir do

predicado

val estados = Map("AL" -> "Alagoas", "AM" -> "Amazonas", "PE" -> "Pernambuco")

val estados2 = estados filter { i => i._1 startsWith "A" } // retorna o mapa("AL" -> "Alagoas","AM" -> "Amazonas")

(26)

Outras operações de Filtering

Operação de Filtering

Nome Exemplo Descrição

distinct List(3, 5, 4, 3, 4).distinct Retorna uma coleção sem elementos duplicados drop List('a', 'b', 'c', 'd') drop 2 Remove os n primeiros

elementos da coleção flatten List(List(1, 2), List(3,4)).flatten Converte uma coleção de

coleções em uma única coleção

Partition List(1, 2, 3, 4, 5) partition(_<3) Particiona a coleção em uma tupla de coleções, de acordo com uma condição

reverse List(1, 2, 3).reverse Gera uma coleção com os elementos revertidos

(27)

Outras operações de Filtering (cont.)

Operação de Filtering

Nome Exemplo Descrição

slice List(2, 3, 5, 7) slice (1, 3) Particiona a coleção de acordo com os índices desejados

sortBy List("apple", "to") sortBy (_.size) Ordena a coleção de acordo com uma função

sorted List("apple", "to").sorted Ordena a coleção na ordem dos elementos

splitAt List(2, 3, 5, 7) splitAt 2 Particiona a coleção em uma tupla a partir de um índice take List(2, 3, 5, 7, 11, 13) take 3 Extrai os primeiros n

elementos da coleção

zip List(1, 2) zip List("a", "b") Combina as coleções em uma lista de tuplas

(28)

Operações de Folding e Reducing

Objetivo: percorrer todos os elementos de uma

coleção, realizando uma operação para cada par de

elementos adjacentes de forma recursiva.

Métodos principais: reduceLeft, foldLeft,

reduceRight e foldRight

Os métodos recebem como parâmetro uma função que

opera sobre dois elementos adjacentes da coleção, gerando

um novo resultado.

O resultado gerado é utilizado na operação com o próximo

elemento da coleção.

(29)

Operações de Folding e Reducing

• Reduz a coleção da esquerda para a direita, começando com os dois primeiros elementos da coleção.

reduceLeft

• Reduz a coleção da direita para a esquerda, começando com os dois últimos elementos da coleção.

reduceRight

• Idem ao reduceLeft, mas com um valor inicial sendo atribuído à operação.

foldLeft

• Idem ao reduceRight, mas com um valor inicial sendo atribuído à operação.

(30)

Operações de Folding e Reducing

Exemplo 1: Soma dos elementos de uma coleção

Vamos mostrar primeiro com os métodos reduce:

val a = Array(12, 6, 15, 2, 20, 9)

a.reduceLeft((x,y) => x + y) // retorna 64

a.reduceLeft(_ + _) // forma concisa, com função parcial

a.reduceLeft(_ * _) // retorna 388800 a.reduceLeft(_ min _) // retorna 2 a.reduceLeft(_ max _) // retorna 20

(31)

Operações de Folding e Reducing

Entendendo como funciona a redução

Vamos usar uma função auxiliar:

Usando o reduceLeft

def maiorValor (x: Int, y: Int) = { val maior = x max y

println(s"comparando $x com $y, o maior é $maior") maior

}

val a = Array(12, 6, 15, 2, 20, 9) a.reduceLeft(maiorValor)

(32)

Operações de Folding e Reducing

Entendendo como funciona a redução

val a = Array(12, 6, 15, 2, 20, 9) a.reduceLeft(maiorValor)

> comparando 12 com 6, o maior é 12 > comparando 12 com 15, o maior é 15 > comparando 15 com 2, o maior é 15 > comparando 15 com 20, o maior é 20 > comparando 20 com 9, o maior é 20 > res1: Int = 20

(33)

Operações de Folding e Reducing

A mesma operação com reduceRight

val a = Array(12, 6, 15, 2, 20, 9) a.reduceRight(maiorValor)

> comparando 20 com 9, o maior é 20 > comparando 2 com 20, o maior é 20 > comparando 15 com 20, o maior é 20 > comparando 6 com 20, o maior é 20 > comparando 12 com 20, o maior é 20 > res2: Int = 20

(34)

Operações de Folding e Reducing

Exemplo 2: Soma dos elementos de uma coleção

com os métodos fold:

val a = Array(1, 2, 3)

a.reduceLeft(_ + _) // retorna 6

a.foldLeft(20)(_ + _) // inicializa a operação com 20 e // ao final retorna 26

(35)

Operações de Folding e Reducing

Exemplo 3: Uso do fold com a função

maiorValor:

val a = Array(12, 6, 15, 2, 20, 9) a.foldLeft(19)(maiorValor)

> comparando 19 com 12, o maior é 19 > comparando 19 com 6, o maior é 19 > comparando 19 com 15, o maior é 19 > comparando 19 com 2, o maior é 19 > comparando 19 com 20, o maior é 20 > comparando 20 com 9, o maior é 20 res3: Int = 20

(36)

Operações de Folding e Reducing

Exemplo 4: Operando com outras coleções:

val nomes = Set("Ana", "José", "João", "Maria")

nomes.reduceLeft((x,y)=> if(x.length > y.length) x else y)

(37)

Outras operações de Folding e Reducing

Operação de Folding e Reducing

Nome Exemplo Descrição

max List(41, 59, 26).max Valor máximo da coleção min List(10.9, 32.5, 4.23, 5.67).min Valor mínimo da coleção product List(5, 6, 7).product Produto dos elementos da

coleção

sum List(5, 6, 7).sum Soma dos elementos da coleção contains List(34, 29, 18) contains 29 Avalia se um elemento pertence a

coleção

endsWith List(0, 4, 3) endsWith List(4,3) Avalia se uma coleção termina com os mesmos elementos de outra coleção

(38)

Outras operações de Folding e Reducing (cont.)

Operação de Folding e Reducing

Nome Exemplo Descrição

exists List(24, 17, 32) exists (_ < 18) Avalia se pelo menos um elemento da coleção atende ao predicado

forall List(24, 17, 32) forall (_ < 18) Avalia se todos os elementos da coleção atendem ao

predicado

startsWith List(0, 4, 3) startsWith List(0) Avalia se uma coleção inicia com os mesmos elementos de outra coleção

scanLeft List(4, 5, 6).scanLeft(0)(_ + _) Idem ao foldLeft, retornando uma coleção dos valores

scanRight List(4, 5, 6).scanRight(0)(_ + _) Idem ao foldRight, retornando uma coleção dos valores

Referências

Documentos relacionados

Por meio destes jogos, o professor ainda pode diagnosticar melhor suas fragilidades (ou potencialidades). E, ainda, o próprio aluno pode aumentar a sua percepção quanto

O petróleo existe na Terra há milhões de anos e, sob diferentes formas físicas, tem sido utilizado em diferentes aplicações desde que o homem existe. Pela sua importância, este

O 6º ano do Mestrado Integrado em Medicina (MIM) é um estágio profissionalizante (EP) que inclui os estágios parcelares de Medicina Interna, Cirurgia Geral,

insights into the effects of small obstacles on riverine habitat and fish community structure of two Iberian streams with different levels of impact from the

Neste estágio, assisti a diversas consultas de cariz mais subespecializado, como as que elenquei anteriormente, bem como Imunoalergologia e Pneumologia; frequentei o berçário

As análises serão aplicadas em chapas de aços de alta resistência (22MnB5) de 1 mm de espessura e não esperados são a realização de um mapeamento do processo

Realizar a manipulação, o armazenamento e o processamento dessa massa enorme de dados utilizando os bancos de dados relacionais se mostrou ineficiente, pois o

Analisar os Relatórios de Frequência Escolar de crianças beneficiárias do Bolsa Família permitiu a identificação dos motivos registrados que levaram muitas crianças e