计数,大小,长度…在Ruby中有太多的select?

我似乎无法find一个明确的答案,我想确保我明白这个“第n级”:-)


     a = {“a”=>“你好”,“b”=>“世界”}
     a.count#2
     a.size#2
     a.length#2

     a = [10,20]
     a.count#2
     a.size#2
     a.length#2

那么哪个使用? 如果我想知道a是否有多个元素,那么它似乎并不重要,但我想确保我理解真正的差异。 这也适用于数组。 我得到相同的结果。

另外,我意识到计数/大小/长度与ActiveRecord有不同的含义。 我现在主要对纯Ruby(1.92)感兴趣,但是如果有人想要了解AR的差异,那么这也是值得赞赏的。

谢谢!

对于数组和哈希sizelength的别名。 他们是同义词,完全一样的东西。

count更通用 – 可以采用元素或谓词,只计算匹配的项目。

 > [1,2,3].count{|x| x > 2 } => 1 

没有提供参数的情况下,它与调用长度的效果基本相同。 虽然可能会有性能差异。

从Array的源代码可以看出,它们几乎完全一样。 这是用于实现array.length的C代码:

 static VALUE rb_ary_length(VALUE ary) { long len = RARRAY_LEN(ary); return LONG2NUM(len); } 

这里是array.count实现的相关部分:

 static VALUE rb_ary_count(int argc, VALUE *argv, VALUE ary) { long n = 0; if (argc == 0) { VALUE *p, *pend; if (!rb_block_given_p()) return LONG2NUM(RARRAY_LEN(ary)); // etc.. } } 

array.count的代码做了一些额外的检查,但最后调用完全相同的代码: LONG2NUM(RARRAY_LEN(ary))

另一方面,Hashes( 源代码 )似乎没有实现自己的count优化版本,所以使用Enumerable ( 源代码 )的实现,它遍历所有的元素并逐一计数。

一般来说,我build议使用length (或其别名size ),而不是count如果你想知道有多less元素完全。


另一方面,对于ActiveRecord而言,存在重要的差异。 看看这个post:

  • 计数ActiveRecord关联:数量,大小还是长度?

使用数据库连接的应用程序有一个关键的区别。

当你使用许多ORM(ActiveRecord,DataMapper等)时,一般的理解是,.size会产生一个请求从数据库中的所有项目('select * from mytable')的查询,然后给你一些项目结果,而.count将生成一个单一的查询('select count(*)from mytable'),这是相当快。

由于这些ORM非常普遍,所以我遵循最less的原则。 一般来说,如果我已经有内存中的东西,那么我使用.size,如果我的代码将生成一个数据库的请求(或通过API的外部服务)我使用.count。

在大多数情况下(例如数组或string ) sizelength别名

count通常来自Enumerable,并且可以带一个可选的谓词块。 因此, enumerable.count {cond}大致是(enumerable.select {cond}).length – 它当然可以绕过中间结构,因为它只需要匹配谓词的数量。

注意:如果count没有被指定,或者在可能的情况下短路到了这个length我不确定count 强制枚举。

编辑(并感谢马克的答案!): 没有块的 count (至less为arrays) 强制评估。 我猜想没有正式的行为,对其他实现来说是“开放的”,如果强制进行一个没有谓词的评估,即使真的有意义。

我在http://blog.hasmanythrough.com/2008/2/27/count-length-sizefind了一个很好的answare

在ActiveRecord中,有几种方法可以找出关联中有多less条logging,而且它们的工作方式也有一些细微的差别。

post.comments.count – 使用SQL COUNT查询确定元素的数量。 您也可以指定条件来仅计算关联元素的一个子集(例如:conditions => {:author_name =>“josh”})。 如果您在关联上设置了计数器caching,则#count将返回caching的值,而不是执行新的查询。

post.comments.length – 这总是将关联的内容加载到内存中,然后返回加载的元素的数量。 请注意,如果关联之前已经加载,那么这将不会强制更新,然后通过其他方式创build新评论(例如Comment.create(…)而不是post.comments.create(…))。

post.comments.size – 这是以前两个选项的组合。 如果集合已经被加载,它将返回它的长度,就像调用#length一样。 如果还没有加载,就像调用#count一样。

另外我有一个亲身经历:

 <%= h(params.size.to_s) %> # works_like_that ! <%= h(params.count.to_s) %> # does_not_work_like_that ! 

我们有几种方法来找出数组中有多less个元素,比如.length.count.size 。 但是,最好使用array.size而不是array.count 。 因为.size在性能上更好。

给Mark Byers增加更多答案。 在Ruby中, array.size方法是Array#length方法的别名。 使用这两种方法没有技术上的区别。 可能你也不会看到任何性能差异。 然而, array.count也做同样的工作,但有一些额外的functionArray#count

它可以用来根据某些条件得到全部的元素。 计数可以通过三种方式调用:

Array#count #返回Array中元素的数量

Array#count n #返回数组中具有值n的元素的数量

arrays#计数{|我| evenven?}根据每个元素数组上调用的条件返回计数

 array = [1,2,3,4,5,6,7,4,3,2,4,5,6,7,1,2,4] array.size # => 17 array.length # => 17 array.count # => 17 

这里所有三种方法都做同样的工作。 但是,这里是count有趣的地方。

让我们说,我想查找数组中包含多less个数组元素,值为2

 array.count 2 # => 3 

该数组共有三个元素,其值为2。

现在,我想查找所有大于4的数组元素

 array.count{|i| i > 4} # =>6 

该arrays共有6个元素大于4。

我希望它给出一些关于count方法的信息。