Eu tenho uma aula de ruby
class MyClass
attr_writer :item1, :item2
end
my_array = get_array_of_my_class() #my_array is an array of MyClass
unique_array_of_item1 = []
Eu quero empurrar MyClass#item1
para unique_array_of_item1
, mas apenas se unique_array_of_item1
ainda não contiver isso item1
. Existe uma solução simples que eu conheço: basta iterar my_array
e verificar se unique_array_of_item1
já contém o atual item1
ou não.
Existe alguma solução mais eficiente?
Set#each
eSet#to_a
) delegado@hash
. E a partir do Ruby 1.9 os hashes são solicitados. "Hashes enumeram seus valores na ordem em que as chaves correspondentes foram inseridas." ruby-doc.org/core-1.9.1/Hash.html@Coorasse tem uma boa resposta , embora devesse ser:
E para atualizar
my_array
no local:fonte
my_array |= [item]
que será atualizadomy_array
no local|=
funciona bem em meus testes com 2.1.1. Descreva seu caso de teste ou abra uma nova pergunta.Você não precisa iterar
my_array
manualmente.Editar:
Como Tombart aponta em seu comentário, o uso
Array#include?
não é muito eficiente. Eu diria que o impacto no desempenho é insignificante para pequenos Arrays, mas você pode querer ir com osSet
maiores.fonte
array.include?(item)
tem complexidadeO(n)
- então é como iterar todo o array. dê uma olhada neste benchmark: gist.github.com/deric/4953652Você pode converter item1 em array e juntá-los:
fonte
|
não||
(ver resposta de Jason)É importante ter em mente que a classe Set e o | (também chamado de "Set Union") produzirá um array de elementos únicos , o que é ótimo se você não quiser duplicatas, mas que será uma surpresa desagradável se você tiver elementos não únicos em seu array original por design.
Se você tiver pelo menos um elemento duplicado em seu array original que não deseja perder, iterar por meio do array com um retorno inicial é o pior caso O (n), o que não é tão ruim no grande esquema das coisas .
fonte
Não tenho certeza se é a solução perfeita, mas funcionou para mim:
fonte