Konrad Wright
Konrad Wright

Reputation: 1264

Ruby find max number w/o running method twice

I want to find the max number without running the function twice

def foo(num)
    num * 10
end

def bar
    x = 0
    for i in 0..5
         if foo(i) > x
             x = foo(i) # I don't want to run foo a second time
         end
    end
end

Upvotes: 0

Views: 97

Answers (6)

Rafa Paez
Rafa Paez

Reputation: 4860

Elegant and simple

foo = -> x { x * 10 }
(1..5).map(&foo).max
# => 50

In one iteration (no so elegant but performs better)

def foo(num); num * 10; end;
(1..5).reduce(-1.0/0) { |a, e| f = foo(e); f > a ? f : a }
# => 50

Upvotes: 0

Arup Rakshit
Arup Rakshit

Reputation: 118289

I would do some change in your code :

def foo(num)
    num * 10
end

def bar
    x = 0
    for i in 0..5
      _,x = [foo(i),x].sort #or you can write as x = [foo(i),x].max
    end
    x
end

p bar
# >> 50

Upvotes: 0

Aaron Cronin
Aaron Cronin

Reputation: 2103

If you want the value of x:

define_method(:foo) { |x| x * 10 } 

(1..5).max_by { |x| foo(x) }                                             
#=> 5

If you want the value of f(x):

(1..5).map { |x| foo(x) }.max
#=> 50

Upvotes: 3

Alex
Alex

Reputation: 699

You can save the result of the function as a variable, so you can use it later without calling the function again.

Applied to your code example, it would look like this:

#...
fooOfI = foo(i)
if fooOfI > x
    x = fooOfI
end
#...

Upvotes: 1

daniel gratzer
daniel gratzer

Reputation: 53901

How about

def bar
  (1..5).map{|i| foo(i)}.max
end

This will traverse 1 to 5, and max a new enumerable with foo(i) instead of i, then return the max.

Upvotes: 4

Matheus Moreira
Matheus Moreira

Reputation: 17030

Store the result of the method in a local variable.

def bar
  x = 0
  for i in 0..5
    foo_result = foo i
    if foo_result > x
      x = foo_result
    end
  end
end

Upvotes: 0

Related Questions