Mi problema es que necesito hacer búsquedas eficientes de si una matriz de 2 elementos y su valor correspondiente es nulo. Así que si tengo las siguientes matrices:
arr1 = [ [1, 2, 100], [3, 4, nil], [5, 6, 101] ]quiero algo como
h = { [1, 2] => 100, [3, 4] => nil, [5, 6] => 101 }Entonces puedo hacer algo como:
error = [] arr2 = [ [1,2], [3,4], [7,8] ] arr2.each do |val| if h.include?(val) if h[val] == nil error << "Value is nil" else # Do something end else error << "Key doesn't exist" end endDado que sobrescribir o ignorar duplicados es aceptable según su comentario.
Puede usar Enumerable#each_with_object para iterar el Array y crear un Hash así
arr1 = [ [1, 2, 100], [3, 4, nil], [5, 6, 101], [1, 2, nil], ] arr1.each_with_object({}) do |(*first_two,last),obj| obj[first_two] = last end #=> {[1, 2]=>nil, [3, 4]=>nil, [5, 6]=>101}Puede ignorar los duplicados de manera similar
arr1.each_with_object({}) do |(*first_two,last),obj| obj[first_two] = last unless obj.key?(first_two) end #=> {[1, 2]=>100, [3, 4]=>nil, [5, 6]=>101}Explicación:
each_with_object({}) pasará cada elemento de arr1 al bloque junto con un objeto (un Hash en este caso)
(*first_two,last),obj - *first_two recopilará todo hasta el last y obj es nuestro Hash
obj[first_two] = last asignación de clave hash simple
each_with_object devuelve el objeto ( obj Hash en este caso)
Actualice según lo recomendado por @Stefan en ruby> = 2.7 que también podría usar
arr1.to_h {|*first_two,last| [first_two, last] }Esta versión sobrescribirá las claves.
arr1 = [ [1, 2, 100], [3, 4, nil], [5, 6, 101] ] result = {} arr1.each { |i| result[i.first(2)] = i.last } => {[1, 2]=>100, [3, 4]=>nil, [5, 6]=>101}Puede desestructurar cada subarreglo durante el mapeo y luego convertir el resultado en hash con el método Array#to_h
arr1 = [ [1, 2, 100], [3, 4, nil], [5, 6, 101], [1, 2, nil], ] arr1.map { |*first_two, last| [first_two, last] }.to_h # => {[1, 2]=>nil, [3, 4]=>nil, [5, 6]=>101}Los duplicados se sobrescribirán