即使 ActiveRecord 模型会实现该map
方法(我不相信),OP 和@xdazz 建议的两个解决方案在时间和内存复杂度方面是等效的。这可以通过这个简单的基准来观察:
require 'fruity'
# Dummy client class
class Client < Struct.new(:first_name, :last_name, :position, :company)
class << self
include Enumerable
def each(&block)
5000.times do
yield Client.new('Firstname', 'Lastname', 'CEO', 'Company Inc.')
end
end
end
alias_method :attributes, :to_h
end
compare do
schnika do
clients = []
Client.each do |client|
clients << client.attributes.values.join(' ')
end
nil
end
xdazz do
clients = Client.map do |client|
client.attributes.values.join(' ')
end
nil
end
end
哪个会输出
schnika is similar to xdazz
此外,当您查看map
( 的同义词collect
) 的实现时,很明显,除了 OP 的方法之外,没有其他任何事情发生:
static VALUE
rb_ary_collect(VALUE ary)
{
long i;
VALUE collect;
RETURN_ENUMERATOR(ary, 0, 0);
collect = rb_ary_new2(RARRAY_LEN(ary));
for (i = 0; i < RARRAY_LEN(ary); i++) {
rb_ary_push(collect, rb_yield(RARRAY_PTR(ary)[i]));
}
return collect;
}
这转化为:
class Array
def collect
collect = []
self.each do |el|
collect << yield(el)
end
collect
end
end