I've been studying a few months, recently I started a full-time job, and I went from studying 8hrs a day to an average of 2.5hrs a day,:( but anyways to the question.
I'm not sure what sugar syntax this is, but let me just show you the problem.
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]
with this being the portion in questioning:
nums
.map { |n| factors(n) }
.inject(:&)
okay, so this is my mental trace: first, map
uses the helper method to get the factors, and outputs the factors into another array, and then that array gets injected?
I think the
.inject(:&)
is what is throwing me off. I ran a quick google on it, but I haven't used inject for many things other than summing arrays, and basic stuff like that. I've also done things like
test = "hello".split("").map(&:upcase)
p test.join
but .inject(:&)
? I know & is a proc, but I've only used them in arguments. I don't know the fundamentals under the hood. Please, take my current level into mind when trying to explain this to me =), I know how the basic inject works, and the splat operator also.
CodePudding user response:
Partial quote form the documentation of Enumerable#inject
.
inject(symbol) → object
[...]
Returns an object formed from operands via either:
A method named by
symbol
.[...]
With method-name argument symbol, combines operands using the method:
# Sum, without initial_operand. (1..4).inject(: ) # => 10
That means in the context of inject
the (:&)
is not a proc but simply the symbol :&
that tells inject what operation to perform to combine the elements in the array.
Let's look at this example:
mutual_factors(8, 4, 10)
#=> [1, 2]
and let's look what happens at each step:
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]
And Array#&
is a method that returns a new array containing each element found in both arrays (duplicates are omitted).