Passing a method call into a method

Hi,

I am trying to figure out how to pass a method call into a method.

I wrote a generic method that call be called on an array of numbers, and returns an array of the index values in the receiver that meet a specified condition:

class Array
  def hash_of_indexes
    if self.empty?
      'The array is empty.'
    else
      h = {}
      self.each_with_index { |e, i| h.include?(e.to_f) ? h[e.to_f] << i : h[e.to_f] = [i] }
      h
    end
  end

  def indexes_of
    self.empty? ? 'The array is empty.' : hash_of_indexes[self.min]
  end
end

puts [1, -100, -200.0, 1000000000000.12, 3, 1, -100, -100, -200].indexes_of.inspect # --> returns [2, 8]

What I'd like to do is to be able to specify what the condition is when calling the array, but can't get that to work right. I tried using yield inside of the square brackets in place of self.min above, and then calling the method with a block with self.min inside the block, but this results in an error (undefined method `min' for main:Object (NoMethodError)).

I have a feeling that I might need to use a lambda or proc to get this to work correctly, but am not sure about the syntax for either of those.

Any help would be appreciated.

Thanks,

Glenn

class Array
def hash_of_indexes
   if self.empty?
     'The array is empty.'
   else
     h = {}
     self.each_with_index { |e, i| h.include?(e.to_f) ? h[e.to_f] << i :
h[e.to_f] = [i] }
     h
   end
end

def indexes_of
   self.empty? ? 'The array is empty.' : hash_of_indexes[self.min]
end
end

What I'd like to do is to be able to specify what the condition is when
calling the array, but can't get that to work right. I tried using yield
inside of the square brackets in place of self.min above, and then calling
the method with a block with self.min inside the block, but this results in
an error (undefined method `min' for main:Object (NoMethodError)).

I have a feeling that I might need to use a lambda or proc to get this to
work correctly, but am not sure about the syntax for either of those.

It's a little unclear from this which part of the procedure you want to
parameterize, but my guess is that you'd do this:

class Array
  def indexes_of(value = nil)
    value = yield(self) if block_given?
    self.empty? ? 'The array is empty.' : hash_of_indexes[value.to_f]
  end
end

Then you'd call it on an array with a value or a block:

some_array.indexes_of(7)
some_array.indexes_of { |ary| ary.min }

My other guess is that you want something like Array#select, but which
returns indexes:

class Array
  def indexes_of
    indexes =
    each_with_index { |e, i| indexes << i if yield(e) }
    indexes
  end
end

[3,9,2,7,4,7].indexes_of { |x| x > 5 }
#=> [1, 3, 5]

To explain, you have a block -- { |x| x > 5 } -- that returns true or false.
Inside your method, you call the block with the current element using
yield(e) to determine whether to add the current index to the list.

class Array
  def hash_of_indexes
    h = {}
    each_with_index{ |e,i|
      e = e.to_f
      h[e] = Array( h[e] ) << i }
    h
  end
end

···

On Sep 14, 8:18 am, Glenn <glenn_r...@yahoo.com> wrote:

[Note: parts of this message were removed to make it a legal post.]

Hi,

I am trying to figure out how to pass a method call into a method.

I wrote a generic method that call be called on an array of numbers, and returns an array of the index values in the receiver that meet a specified condition:

class Array
  def hash_of_indexes
    if self.empty?
      'The array is empty.'
    else
      h = {}
      self.each_with_index { |e, i| h.include?(e.to_f) ? h[e.to_f] << i : h[e.to_f] = [i] }
      h
    end
  end

Glenn wrote:

class Array
  def hash_of_indexes
    if self.empty?
      'The array is empty.'
    else
      h = {}
      self.each_with_index { |e, i| h.include?(e.to_f) ? h[e.to_f] << i
: h[e.to_f] = [i] }
      h
    end
  end

  def indexes_of
    self.empty? ? 'The array is empty.' : hash_of_indexes[self.min]
  end
end

Use send, as in:

class Array
  def indexes_of(function)
    self.empty? ? 'The array is empty.' :
hash_of_indexes[self.send(function)]
  end
end

puts [1, -100, -200.0, 1000000000000.12, 3, 1, -100, -100,
-200].indexes_of(:min)

···

--
Posted via http://www.ruby-forum.com/\.