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

时间:2010-12-29 01:02:08

标签: ruby activerecord size 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的差异,那也会受到赞赏。

谢谢!

6 个答案:

答案 0 :(得分:191)

对于数组和哈希sizelength的别名。它们是同义词,完全相同。

count更通用 - 它可以使用元素或谓词,只计算那些匹配的项目。

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

如果提供参数来计算,它与调用长度基本相同。但是可能存在性能差异。

我们可以从source code for 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))

另一方面,

哈希(source code)似乎没有实现自己的count优化版本,因此使用Enumerablesource code)的实现,它遍历所有元素并逐个计算。

一般情况下,如果您想知道共有多少元素,我建议您使用length(或其别名size)而不是count


另一方面,关于ActiveRecord,重要的差异。看看这篇文章:

答案 1 :(得分:10)

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

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

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

答案 2 :(得分:7)

在大多数情况下(例如ArrayStringsizelength别名

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

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

编辑(感谢Mark的回答!): count 没有阻止(至少对于阵列)强迫进行评估。我认为如果没有正式的行为,它对其他实现来说是“开放的”,如果在没有谓词的情况下强迫评估甚至真的有意义。

答案 3 :(得分:5)

我在http://blog.hasmanythrough.com/2008/2/27/count-length-size

找到了一个很好的answare
  

在ActiveRecord中,有几种方法可以找出记录的数量   是一个协会,在如何有一些微妙的差异   他们工作。

     

post.comments.count - 使用SQL确定元素的数量   COUNT个查询。您还可以指定条件以仅计算其子集   相关元素(例如:conditions => {:author_name =>   “乔希”})。如果在关联上设置计数器缓存,则为#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 !

答案 4 :(得分:2)

我们有几种方法可以找出数组中有多少元素,例如.length.count.size。但是,最好使用array.size而不是array.count。因为.size的效果更好。

答案 5 :(得分:1)

为Mark Byers答案添加更多内容。在Ruby中,方法array.sizeArray#length方法的别名。使用这两种方法中的任何一种都没有技术差异。可能你也不会看到性能上的任何差异。但是,array.count也执行相同的工作,但具有一些额外的功能Array#count

它可以用于根据某些条件获得元素的总数。可以通过三种方式调用Count:

数组#count #返回数组

中的元素数

数组#count n #返回数组

中值为n的元素数

<强>阵列#计数{| I | 38.ven?} 根据在每个元素数组上调用的条件返回计数

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变得有趣。

让我们说,我想找到数组中包含多少数组元素的值 2

array.count 2    # => 3

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

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

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

该阵列总共有6个元素>比4.

我希望它提供有关count方法的一些信息。