Cómo encontrar y devolver un valor duplicado en una matriz
arr
es una matriz de cadenas:
["hello", "world", "stack", "overflow", "hello", "again"]
¿Cuál sería una forma fácil y elegante de comprobar si arr
hay duplicados y, de ser así, devolver uno de ellos (sin importar cuál)?
Ejemplos:
["A", "B", "C", "B", "A"] # => "A" or "B"
["A", "B", "C"] # => nil
a = ["A", "B", "C", "B", "A"]
a.detect{ |e| a.count(e) > 1 }
Sé que esta no es una respuesta muy elegante, pero me encanta. Es un hermoso código de una sola línea. Y funciona perfectamente bien a menos que necesite procesar un gran conjunto de datos.
¿Busca una solución más rápida? ¡Aquí tienes!
def find_one_using_hash_map(array)
map = {}
dup = nil
array.each do |v|
map[v] = (map[v] || 0 ) + 1
if map[v] > 1
dup = v
break
end
end
return dup
end
Es lineal, O(n), pero ahora necesita administrar múltiples líneas de código, necesita casos de prueba, etc.
Si necesita una solución aún más rápida, tal vez pruebe con C.
Y aquí está la esencia comparando diferentes soluciones: https://gist.github.com/naveed-ahmad/8f0b926ffccf5fbd206a1cc58ce9743e
Puedes hacer esto de varias maneras, siendo la primera opción la más rápida:
ary = ["A", "B", "C", "B", "A"]
ary.group_by{ |e| e }.select { |k, v| v.size > 1 }.map(&:first)
ary.sort.chunk{ |e| e }.select { |e, chunk| chunk.size > 1 }.map(&:first)
Y una opción O(N^2) (es decir, menos eficiente):
ary.select{ |e| ary.count(e) > 1 }.uniq