计数,大小,长度…在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的差异,那么这也是值得赞赏的。
谢谢!
对于数组和哈希size
是length
的别名。 他们是同义词,完全一样的东西。
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 ) size
是length
的别名 。
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
方法的信息。