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 (ex.: Alice:88,Bob:42,Charlie:75). Use group_by seguido por partition para produzir um relatório resumido.
Passos:
- Faça o parse de cada entrada para um par
[name, score](score é um número inteiro) - Agrupe com
group_bypela primeira letra donamedo par (em maiúscula) - Para cada grupo de letras, em ordem
alphabetical, apliquepartitionnas entradas dividindo entre aprovados (score >= 60) e reprovados, depois 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 sua ordem original. Se um dos lados não tiver nomes, deixe-o vazio (ex.: 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 a Fundo
Visão Geral de Métodos de StringInterpolação de StringsIterando sobre StringsSplit e JoinRecapitulação - String Weaver4Blocos, Procs e Lambdas
O que é um Bloco?do..end vs ChavesA palavra-chave yieldParâmetros de BlocoProcs e LambdasRecapitulação - Iterador Customizado7Hashes Parte 2
Hash.new com Valores PadrãoIterando em 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 / WhenRecapitulação - Prática com Intervalos5O Poder do Enumerable
Select e RejectEncadeando o MapReduce / Injectcount, all?, any?, none?group_by e partitionsort_by, min_by, max_byRecapitulação - Data PipelinePratique por conta própria: Compilador de Ruby online