Search code examples
rubyinjectenumerable

custom ruby inject method not producing expected output


forgive me I see that this question has been asked in many ways here on forums but none have output the desired output and I have been stuck for a few days reading different explanations of how the inject method works. Could my code be inspected and seen where or what it that I'm doing wrong or lacking? I'm learning the language and don't want to get frustrated over my inexperience.

my code:


  def my_inject(initial = nil, sym = nil, &block)
    check = initial.nil?
    acc = check ? 0 : 1


    if block_given?
      my_each { |x| acc = yield(acc, x) }
      end
    acc
  end
alias_method :my_reduce, :my_inject

i have been testing with the test cases from ruby_doc.org. the test cases:

# Sum some numbers
(5..10).reduce(:+)                             #=> 45
# Same using a block and inject
(5..10).inject { |sum, n| sum + n }            #=> 45
# Multiply some numbers
(5..10).reduce(1, :*)                          #=> 151200
# Same using a block
(5..10).inject(1) { |product, n| product * n } #=> 151200
# find the longest word
longest = %w{ cat sheep bear }.inject do |memo, word|
   memo.length > word.length ? memo : word
end
longest                                        #=> "sheep"

My code works with all that has a block except the last one that returns sheep. An insight into what I'm doing wrong is much appreciated.

ok this is what i have now:

  def my_inject(initial = nil, sym = nil, &block)
    acc = initial.nil? ? 0 : 1
    sym ||= initial if initial.is_a? Symbol
    if !block_given?
      block = sym.to_proc
      my_each { |x| acc = block.call(acc, x) }
    else
      my_each { |x| acc = yield(acc, x) }
      end
    acc
  end
  alias_method :my_reduce, :my_inject

it works with the first four test cases, but not the 5th, also the first test case returns 46 instead of 45 which it's because of the check that I used but I've tried others that didn't work


Solution

  • I was able to solve it with code.

     def my_inject(initial = nil, second = nil)
        arr = is_a?(Array) ? self : to_a
        sym = initial if initial.is_a?(Symbol) || initial.is_a?(String)
        acc = initial if initial.is_a? Integer
    
        if initial.is_a?(Integer)
          sym = second if second.is_a?(Symbol) || second.is_a?(String)
        end
    
        if sym
          arr.my_each { |x| acc = acc ? acc.send(sym, x) : x }
        elsif block_given?
          arr.my_each { |x| acc = acc ? yield(acc, x) : x }
        end
        acc
      end
      alias my_reduce my_injec