-1

How can I write a Ruby function that can calculate the average of an array? If the array doesn't have any elements, the result should be 0. I should use a loop for the implementation. I started like this, but I'm not quite sure how to use the loop.

a = [1, 2, 3, 4, 5, 6]

def average(a)  
  sum = 0.0
  result = 0.0
  if array.length > 0 then
    array.each do |item|
      sum += item
    end
    result = sum / array.length
  end
  return result.to_f
end
11
  • 1
    Possible duplicate of How do I create an average from a Ruby array? Commented Dec 15, 2018 at 16:51
  • The only difference is you're trying to wrap the average calculation in a method. Commented Dec 15, 2018 at 16:51
  • I'm confused... what does that mean 'trying to wrap the average calculation in a method'? Commented Dec 15, 2018 at 16:55
  • About your question and the possible duplicate. Commented Dec 15, 2018 at 17:02
  • 3
    If your exercise instructions are confusing, the most likely person to help you, is the person who gets paid to make sure your exercise instructions are not confusing, i.e. your TA / instructor / teacher / professor. Random anonymous people on the interwebs cannot really read your instructor's mind, I'm afraid. When I was confronted with exercises like this, I would simply solve them several different ways, e.g. with a library method, a higher-order function, tail-recursion, and a loop, and then discuss the pros and cons of those 4 approaches. Commented Dec 15, 2018 at 17:52

4 Answers 4

1
def average(arr, precision=0)
  return 0 if arr.empty?
  arr.sum.fdiv(arr.size).round(precision)
end

arr = [1,2,3,7]

average(arr)   #=> 3
average(arr,2) #=> 3.25

Rather than using Integer#fdiv you could write

(arr.sum.to_f/arr.size).round(precision)
Sign up to request clarification or add additional context in comments.

Comments

0

I suppose we can also write it simply as below

a = [1, 2, 3, 4, 5, 6]
def average(arr=[])  
  sum = 0.0
  i=0
  while(i < arr.length) do
    sum += arr[i].to_f
    i += 1
  end
  return ((i==0) ? 0 : (sum / i))
end

We can loop and calculate sum this way. Afterwards for average we took value of i which will be retained value after loop and make conditional operator for returning result.

Its simple solution, I have not tested it though so can have mistakes. You can try on your side. Hope This helps !!

8 Comments

Thank you for your help! Which function does the 'i = 0' have?
just a measure that 'i' will not be local to the while loop and will be available outside plus it initializes the variable. Did I get your question here?
Yes I think I get it now. Can you maybe explain why you used '?' in the return-part?
its a conditional operator ? : which is like if..else..end block in short. It is used to prevent devide-by-zero error if 'i' is 0. It says if 'i' is 0 then return 0 else divide sum by 'i' to get average which will be float as sum is in decimals.
If you want more info on the conditional operator (also called ternary operator), this is a good answer on SO: stackoverflow.com/a/4252945/249353
|
0

You can write this:

def average(values)
    total = 0.0

    values.each do |i| 
        total += i
    end

    return total / values.length()
end

If you want to use a loop, you can do it this way:

def average(values=[])
    total = 0.0

    for i in values
        total += i
    end

    return total / values.length()
end

If a non-empty array is passed, it will return the average of the values. If an empty array is passed, it will return 0.0.

You can test it like this:

puts average([1, 2, 3, 4, 5]) #=> "3"
puts average([]) #=> "0"

5 Comments

Did you actually run your code? It produces neither "3" nor "0"
@Stefan those are the results it's producing for me.
Your second example is not more of a loop than the first one. for / in is simply syntactic sugar for each (with slightly different semantics for variable binding), so your two examples are more or less the same. The only actual loop construct Ruby has, is the while loop.
@Davidthethird interesting, I get 3.0 and NaN
@JörgWMittag the OP wanted to use a loop, so I used an example with a loop.
0
def average(a)
  if a.empty?
    0
  else
    sum = a.inject(0.0){|x, sum| sum += x}
    sum / a.size.to_f
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.