数量,大小,长度...... Ruby中的选择太多了?

cbm*_*eks 139 ruby size activerecord content-length

我似乎无法在此找到明确的答案,我想确保我理解为"第n级":-)


    a = { "a" => "Hello", "b" => "World" }
    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的差异,那也会受到赞赏.

谢谢!

Mar*_*ers 193

对于数组和散列size是别名length.它们是同义词,完全相同.

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

> [1,2,3].count{|x| x > 2 }
=> 1
Run Code Online (Sandbox Code Playgroud)

如果您没有提供计数参数,它与调用长度的效果基本相同.但是可能存在性能差异.

我们可以从Array源代码中看到它们几乎完全相同.以下是实现的C代码array.length:

static VALUE
rb_ary_length(VALUE ary)
{
    long len = RARRAY_LEN(ary);
    return LONG2NUM(len);
}
Run Code Online (Sandbox Code Playgroud)

以下是实施的相关部分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..
    }
}
Run Code Online (Sandbox Code Playgroud)

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

另一方面,哈希(源代码)似乎没有实现自己的优化版本,count因此使用Enumerable(源代码)实现,它迭代所有元素并逐个计数.

一般来说,我建议使用length(或其别名size),而不是count如果你想知道有多少元素.


关于ActiveRecord的,而另一方面,也重要的区别.看看这篇文章:

  • +1 Yay去源头并回答我的沉思:-) (10认同)

ste*_*tef 10

使用数据库连接的应用程序存在重大差异.

当您使用许多ORM(ActiveRecord,DataMapper等)时,一般的理解是.size将生成一个查询,该请求从数据库中请求所有项目('select*from mytable'),然后为您提供项目数结果,而.count将生成一个查询('mytable'中的'select count(*)),这要快得多.

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


小智 7

在大多数情况下(例如阵列字符串)size是一个别名length.

count通常来自Enumerable,可以使用可选的谓词块.因此enumerable.count {cond}[粗略] (enumerable.select {cond}).length- 它当然可以绕过中间结构,因为它只需要匹配谓词的计数.

注意:我不确定是否count 强制对枚举进行评估,如果未指定块,或者length如果可能则将其短路.

编辑(感谢Mark的回答!): count 没有块(至少对于Arrays)不会强制进行评估.我认为如果没有正式的行为,它对其他实现来说是"开放的",如果在没有谓词的情况下强制进行评估甚至真正有意义.


pro*_*ica 5

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

在ActiveRecord中,有几种方法可以找出关联中有多少条记录,并且它们的工作方式存在一些细微差别.

post.comments.count - 确定具有SQL COUNT查询的元素数.您还可以指定条件以仅计算关联元素的子集(例如:conditions => {:author_name =>"josh"}).如果在关联上设置计数器缓存,#count将返回该缓存值,而不是执行新查询.

post.comments.length - 这总是将关联的内容加载到内存中,然后返回加载的元素数.请注意,如果先前已加载关联,然后通过其他方式创建新注释(例如,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 !
Run Code Online (Sandbox Code Playgroud)