O Ruby tem dois métodos que, apesar de pouco usados no dia a dia, podem te ajudar a resolver alguns problemas.
Vamos supor que temos uma lista de nomes de cidades gravadas numa coleção:
cidades = [‘São Paulo’, ‘Brasília’, ‘Rio de Janeiro’, ‘Curitiba’]
Mas, infelizmente, só podemos visitar 3 delas, então seria interessante ver uma lista com todas as possibilidades de rotas disponíveis para termos uma ideia se aquela rota é interessante.
Para isso podemos usar o método permutation
:
cidades.permutation(3).to_a
# => [["São Paulo", "Brasília", "Rio de Janeiro"], ["São Paulo", "Brasília", "Curitiba"], ["São Paulo", "Rio de Janeiro", "Brasília"], ["São Paulo", "Rio de Janeiro", "Curitiba"], ["São Paulo", "Curitiba", "Brasília"], ["São Paulo", "Curitiba", "Rio de Janeiro"], ["Brasília", "São Paulo", "Rio de Janeiro"], ["Brasília", "São Paulo", "Curitiba"], ["Brasília", "Rio de Janeiro", "São Paulo"], ["Brasília", "Rio de Janeiro", "Curitiba"], ["Brasília", "Curitiba", "São Paulo"], ["Brasília", "Curitiba", "Rio de Janeiro"], ["Rio de Janeiro", "São Paulo", "Brasília"], ["Rio de Janeiro", "São Paulo", "Curitiba"], ["Rio de Janeiro", "Brasília", "São Paulo"], ["Rio de Janeiro", "Brasília", "Curitiba"], ["Rio de Janeiro", "Curitiba", "São Paulo"], ["Rio de Janeiro", "Curitiba", "Brasília"], ["Curitiba", "São Paulo", "Brasília"], ["Curitiba", "São Paulo", "Rio de Janeiro"], ["Curitiba", "Brasília", "São Paulo"], ["Curitiba", "Brasília", "Rio de Janeiro"], ["Curitiba", "Rio de Janeiro", "São Paulo"], ["Curitiba", "Rio de Janeiro", "Brasília"]]
Pausa na historinha!
Antes de continuar, uma operação interessante para discutirmos é porque temos que chamar to_a
para converter em array no final.
Essa chamada é necessária para ver o resultado, porque não temos nenhuma ação com os dados depois de transformá-los como um map
ou each
. Como o retorno do método permutation
é um Enumerator
e só queremos mostrar os valores, o to_a
se torna necessário.
cidades.permutation(3)
# => #<Enumerator: ["São Paulo", "Brasília", "Rio de Janeiro", "Curitiba"]:permutation(3)>
Play na historinha!
Agora temos uma lista de cidades em todas as ordens possíveis. Por exemplo, a rota de São Paulo até Brasília e Rio de Janeiro aparece em diversas ordens:
[["São Paulo", "Brasília", "Rio de Janeiro"], ["São Paulo", "Rio de Janeiro", "Brasília"], ["Brasília", "São Paulo", "Rio de Janeiro"], ["Brasília", "Rio de Janeiro", "São Paulo"], ["Rio de Janeiro", "São Paulo", "Brasília"], ["Rio de Janeiro", "Brasília", "São Paulo"]]
Isso pode ser um problema, você pode querer só olhar as 3 cidades e pensar se elas são legais, independente da ordem!
Para chegar nesse retorno, podemos usar o método combination
:
cidades.combination(3).to_a
# => [["São Paulo", "Brasília", "Rio de Janeiro"], ["São Paulo", "Brasília", "Curitiba"], ["São Paulo", "Rio de Janeiro", "Curitiba"], ["Brasília", "Rio de Janeiro", "Curitiba"]]
Agora temos todas as combinações de cidades, mas sem nenhuma repetição entre elas como no exemplo anterior.
Além destes, na doc do Ruby também temos os métodos repeated_permutations
e repeated_combinations
, onde elementos podem se repetir. Vamos ver um exemplo usando repeated_combinations
com as cidades acima:
cidades.repeated_combination(3).to_a
# => [["São Paulo", "São Paulo", "São Paulo"], ["São Paulo", "São Paulo", "Brasília"], ["São Paulo", "São Paulo", "Rio de Janeiro"], ["São Paulo", "São Paulo", "Curitiba"], ["São Paulo", "Brasília", "Brasília"], ["São Paulo", "Brasília", "Rio de Janeiro"], ["São Paulo", "Brasília", "Curitiba"], ["São Paulo", "Rio de Janeiro", "Rio de Janeiro"], ["São Paulo", "Rio de Janeiro", "Curitiba"], ["São Paulo", "Curitiba", "Curitiba"], ["Brasília", "Brasília", "Brasília"], ["Brasília", "Brasília", "Rio de Janeiro"], ["Brasília", "Brasília", "Curitiba"], ["Brasília", "Rio de Janeiro", "Rio de Janeiro"], ["Brasília", "Rio de Janeiro", "Curitiba"], ["Brasília", "Curitiba", "Curitiba"], ["Rio de Janeiro", "Rio de Janeiro", "Rio de Janeiro"], ["Rio de Janeiro", "Rio de Janeiro", "Curitiba"], ["Rio de Janeiro", "Curitiba", "Curitiba"], ["Curitiba", "Curitiba", "Curitiba"]]
Note que “São Paulo”, pode aparecer várias vezes, como no primeiro elemento onde aparece 3 vezes.
É isso! Temos então bons métodos que podem nos ajudar a analisar dados!