在Ruby中重新实现Enumerable Map方法

and*_*ent 4 ruby ruby-on-rails map

我正在红宝石店练习实习.我期待的一个工作问题是重新实现一个可枚举的方法.

我正在尝试立即实现地图,我无法弄清楚如何实现没有给出块的情况.

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

使用我当前的实现.如果我跑:

[1,2,3,4,5,6].mapp{|each| each+1} #returns => [2,3,4,5,6,7]
Run Code Online (Sandbox Code Playgroud)

但是,我不确定如何获取未传入块的情况:

[1,2,3,4].mapp("cat") # should return => ["cat", "cat", "cat", "cat"]
Run Code Online (Sandbox Code Playgroud)

如果有人能指出我正确的方向.我真的很感激.我尝试查看源代码,但似乎做的事情与我习惯的完全不同.

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;
}
Run Code Online (Sandbox Code Playgroud)

fot*_*nus 8

我想[1,2,3,4].mapp("cat")你的意思是[1,2,3,4].mapp{"cat"}.

也就是说,没有块的map返回一个枚举器:

 [1,2,3,4].map
 => #<Enumerator: [1, 2, 3, 4]:map>
Run Code Online (Sandbox Code Playgroud)

这是相同的输出 to_enum

[1,2,3,4].to_enum
 => #<Enumerator: [1, 2, 3, 4]:each> 
Run Code Online (Sandbox Code Playgroud)

所以在你的代码中,你只想调用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
Run Code Online (Sandbox Code Playgroud)