group_by e partition
Parte da seção Lógica e Fluxo do Journey de Ruby da Coddy. Lição 25 de 56.
Às vezes você quer dividir uma coleção em vez de filtrá-la. Dois métodos cobrem a maioria dos casos.
group_by recebe um bloco e retorna um hash. Cada resultado único do bloco se torna uma chave, mapeando para uma array dos elementos que o produziram:
words = ["hi", "hello", "yo", "hey", "bonjour"]
by_length = words.group_by { |w| w.length }
puts by_length.inspect
# {2=>["hi", "yo"], 5=>["hello"], 3=>["hey"], 7=>["bonjour"]}É a maneira mais limpa de agrupar itens em uma única passagem.
partition é a versão binária: ele retorna um par de arrays, os elementos onde o bloco foi verdadeiro, e o restante:
evens, odds = [1, 2, 3, 4, 5].partition { |n| n.even? }
puts evens.inspect # [2, 4]
puts odds.inspect # [1, 3, 5]Use partition quando houver exatamente dois baldes, group_by quando puder haver muitos.
Desafio
MédioLeia uma lista separada por vírgulas de entradas name:score (por exemplo, Alice:88,Bob:42,Charlie:75). Use group_by seguido de partition para produzir um pequeno relatório.
Etapas:
- Analise cada entrada em um par
[name, score](score é um inteiro) - Aplique
group_byà primeira letra denamedo par (em maiúsculas) - Para cada grupo de letras, em ordem alfabética, aplique
partitionàs entradas, separando-as em aprovadas (score >= 60) e reprovadas, e então imprima uma linha por grupo:
<LETTER>: pass=<names_passing_joined_by_comma> fail=<names_failing_joined_by_comma>Dentro de cada grupo, os nomes aparecem na ordem original. Se um dos lados não tiver nomes, deixe-o vazio (por exemplo, fail=).
Para a entrada Alice:88,Adam:42,Bob:75,Beth:55,Cara:90, a saída é:
A: pass=Alice fail=Adam
B: pass=Bob fail=Beth
C: pass=Cara fail=Experimente você mesmo
entries = gets.chomp.split(",").map do |s|
name, score = s.split(":")
[name, score.to_i]
end
# TODO: agrupe pela primeira letra (maiúscula), particione cada grupo por pontuação >= 60,
# imprima 'X: pass=... fail=...' em ordem alfabética das letras
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Lógica e Fluxo
1Strings em Profundidade
Visão Geral dos Métodos de StringInterpolação de StringsPercorrendo StringsDividir e UnirRecapitulação - String Weaver4Blocos, Procs e Lambdas
O que é um Bloco?do..end vs ChavesA Palavra-chave yieldParâmetros de BlocoProcs e LambdasRevisão - Iterador Personalizado7Hashes - Parte 2
Hash.new com Valores PadrãoIterando sobre HashesHashes AninhadosMesclando e TransformandoRecapitulação - Contador de Frequência10Projeto - Registros de Alunos
Visão Geral do ProjetoAdicionar Aluno2Intervalos
O que é um intervalo?Métodos de intervaloIntervalos em Case / WhenRevisão - Prática com intervalos5Potência do Enumerable
Select e RejectEncadeando MapReduce / Injectcount, all?, any?, none?group_by e partitionsort_by, min_by, max_byRecapitulação - Pipeline de DadosPratique por conta própria: Compilador de Ruby online