No estoy seguro de qué sintaxis de azúcar es esta, pero déjame mostrarte el problema.
def factors num (1..num).select {|n| num % n == 0} end def mutual_factors(*nums) nums .map { |n| factors(n) } .inject(:&) end p mutual_factors(50, 30) # [1, 2, 5, 10] p mutual_factors(50, 30, 45, 105) # [1, 5] p mutual_factors(8, 4) # [1, 2, 4] p mutual_factors(8, 4, 10) # [1, 2] p mutual_factors(12, 24) # [1, 2, 3, 4, 6, 12] p mutual_factors(12, 24, 64) # [1, 2, 4] p mutual_factors(22, 44) # [1, 2, 11, 22] p mutual_factors(22, 44, 11) # [1, 11] p mutual_factors(7) # [1, 7] p mutual_factors(7, 9) # [1]siendo esta la porción en cuestión:
nums .map { |n| factors(n) } .inject(:&) bien, este es mi rastro mental: primero, el map usa el método auxiliar para obtener los factores, y los envía a otra matriz, y luego esa matriz se inyecta.
Pienso que el
.inject(:&)es lo que me está echando para atrás. Busqué rápidamente en Google, pero no he usado inyectar para muchas cosas además de sumar matrices y cosas básicas como esa. También he hecho cosas como
test = "hello".split("").map(&:upcase) p test.join pero .inject(:&) ? Lo sé y es un proceso, pero solo los he usado en argumentos. No sé los fundamentos debajo del capó. Por favor, tenga en cuenta mi nivel actual cuando intente explicarme esto =), sé cómo funciona la inyección básica y también el operador splat.
Cita parcial de la documentación de Enumerable#inject .
inyectar (símbolo) → objeto
[...]
Devuelve un objeto formado a partir de operandos a través de:
Un método nombrado por el
symbol.[...]
Con símbolo de argumento de nombre de método, combina operandos usando el método:
# Sum, without initial_operand. (1..4).inject(:+) # => 10
Eso significa que en el contexto de inject (:&) no es un proceso sino simplemente el símbolo :& que le dice a inyectar qué operación realizar para combinar los elementos en la matriz.
Veamos este ejemplo:
mutual_factors(8, 4, 10) #=> [1, 2]y veamos que pasa en cada paso:
nums .map { |n| factors(n) } #=> [[1, 2, 4, 8], [1, 2, 4], [1, 2, 5, 10]] .inject(:&) #=> [1, 2, 4, 8] & [1, 2, 4] & [1, 2, 5, 10] Y Array#& es un método que devuelve una nueva matriz que contiene cada elemento que se encuentra en ambas matrices (se omiten los duplicados).