Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reimplementing Enumerable Map method in Ruby

I'm practicing for an internship interview at a ruby shop. One of the job questions I'm expecting is to reimplement an enumerable method.

I'm trying to implement map right now and I'm having trouble figuring out how to implement the case where a block is not given.

class Array
    def mapp()
      out = []
      if block_given?
        self.each { |e| out << yield(e) }
      else
        <-- what goes here? -->
      end
   out
   end
 end

Using my current implementation. If I run:

[1,2,3,4,5,6].mapp{|each| each+1} #returns => [2,3,4,5,6,7]

However, I'm not sure how to get cases where a block isn't passed in:

[1,2,3,4].mapp("cat") # should return => ["cat", "cat", "cat", "cat"]

If someone could point me in the right direction. I'd really appreciate it. I tried looking through the source code but it seems to do things very differently than what i'm used to.

static VALUE
enum_flat_map(VALUE obj)
{
VALUE ary;

RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size);

ary = rb_ary_new();
rb_block_call(obj, id_each, 0, 0, flat_map_i, ary);

return ary;
}
like image 547
android_student Avatar asked May 07 '13 15:05

android_student


People also ask

How do you use the map method in Ruby?

The way the map method works in Ruby is, it takes an enumerable object, (i.e. the object you call it on), and a block. Then, for each of the elements in the enumerable, it executes the block, passing it the current element as an argument. The result of evaluating the block is then used to construct the resulting array.

What is enumerable in Ruby?

In Ruby, we call an object enumerable when it describes a set of items and a method to loop over each of them. The built-in enumerables get their enumeration features by including the Enumerable module, which provides methods like #include? , #count , #map , #select and #uniq , amongst others.

What does &: mean in Ruby?

What you are seeing is the & operator applied to a :symbol . In a method argument list, the & operator takes its operand, converts it to a Proc object if it isn't already (by calling to_proc on it) and passes it to the method as if a block had been used.

How do you create a map in Ruby?

Ruby Map SyntaxFirst, you have an array, but it could also be a hash, or a range. Then you call map with a block. The block is this thing between brackets { ... } . Inside the block you say HOW you want to transform every element in the array.


1 Answers

I suppose that by [1,2,3,4].mapp("cat") you mean [1,2,3,4].mapp{"cat"}.

That said, map without a block returns an enumerator:

 [1,2,3,4].map
 => #<Enumerator: [1, 2, 3, 4]:map>

That is the same output of to_enum

[1,2,3,4].to_enum
 => #<Enumerator: [1, 2, 3, 4]:each> 

So in your code, you just want to call to_enum:

class Array
    def mapp()
        out = []
        if block_given?
            self.each { |e| out << yield(e) }
        else
            out = to_enum :mapp
        end
        out
    end
end
like image 58
fotanus Avatar answered Oct 18 '22 21:10

fotanus