数量、大小、长度……Ruby 中的选择太多?

发布于 2024-10-09 16:09:02 字数 411 浏览 0 评论 0原文

我似乎无法找到一个明确的答案,我想确保我理解这一点到“第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 带来的差异,我也将不胜感激。

谢谢!

I can't seem to find a definitive answer on this and I want to make sure I understand this to the "n'th level" :-)


    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

So which to use? If I want to know if a has more than one element then it doesn't seem to matter but I want to make sure I understand the real difference. This applies to arrays too. I get the same results.

Also, I realize that count/size/length have different meanings with ActiveRecord. I'm mostly interested in pure Ruby (1.92) right now but if anyone wants to chime in on the difference AR makes that would be appreciated as well.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

厌味 2024-10-16 16:09:02

对于数组和哈希 size< /a> 是 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 的相关部分: 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..
    }
}

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

哈希值(源代码) 另一方面似乎没有实现他们自己的优化版本 count 因此来自 Enumerable 的实现 (源代码),它迭代所有元素并对它们进行计数一对一。

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


另一方面,对于 ActiveRecord,存在一些重要的差异。查看这篇文章:

For arrays and hashes size is an alias for length. They are synonyms and do exactly the same thing.

count is more versatile - it can take an element or predicate and count only those items that match.

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

In the case where you don't provide a parameter to count it has basically the same effect as calling length. There can be a performance difference though.

We can see from the source code for Array that they do almost exactly the same thing. Here is the C code for the implementation of array.length:

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

And here is the relevant part from the implementation of 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..
    }
}

The code for array.count does a few extra checks but in the end calls the exact same code: LONG2NUM(RARRAY_LEN(ary)).

Hashes (source code) on the other hand don't seem to implement their own optimized version of count so the implementation from Enumerable (source code) is used, which iterates over all the elements and counts them one-by-one.

In general I'd advise using length (or its alias size) rather than count if you want to know how many elements there are altogether.


Regarding ActiveRecord, on the other hand, there are important differences. check out this post:

海的爱人是光 2024-10-16 16:09:02

对于使用数据库连接的应用程序来说,存在一个至关重要的区别。

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

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

There is a crucial difference for applications which make use of database connections.

When you are using many ORMs (ActiveRecord, DataMapper, etc.) the general understanding is that .size will generate a query that requests all of the items from the database ('select * from mytable') and then give you the number of items resulting, whereas .count will generate a single query ('select count(*) from mytable') which is considerably faster.

Because these ORMs are so prevalent I following the principle of least astonishment. In general if I have something in memory already, then I use .size, and if my code will generate a request to a database (or external service via an API) I use .count.

幽梦紫曦~ 2024-10-16 16:09:02

在大多数情况下(例如 ArrayString) size别名 >长度。

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

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

编辑(感谢马克的回答!): 计数 没有块(至少对于数组)强制评价。我想如果没有正式的行为,它对其他实现是“开放的”,如果在没有谓词的情况下强制进行评估确实有意义的话。

In most cases (e.g. Array or String) size is an alias for length.

count normally comes from Enumerable and can take an optional predicate block. Thus enumerable.count {cond} is [roughly] (enumerable.select {cond}).length -- it can of course bypass the intermediate structure as it just needs the count of matching predicates.

Note: I am not sure if count forces an evaluation of the enumeration if the block is not specified or if it short-circuits to the length if possible.

Edit (and thanks to Mark's answer!): count without a block (at least for Arrays) does not force an evaluation. I suppose without formal behavior it's "open" for other implementations, if forcing an evaluation without a predicate ever even really makes sense anyway.

流年里的时光 2024-10-16 16:09:02

我在 http://blog.hasmanythrough.com/2008 找到了一个很好的答案/2/27/计数长度大小

在ActiveRecord中,有几种方法可以查出有多少条记录
处于一个协会中,并且在如何进行方面存在一些细微的差异
他们工作。

post.comments.count - 使用 SQL 确定元素数量
COUNT 查询。您还可以指定条件来仅计算一部分
关联元素(例如 :conditions => {:author_name =>
“乔希”})。如果您在关联上设置计数器缓存,#count
将返回缓存的值而不是执行新的查询。

post.comments.length - 这总是加载的内容
关联到内存中,然后返回加载的元素数。
请注意,如果关联已经存在,这不会强制更新
先前加载,然后通过另一个创建新评论
方式(例如 Comment.create(...) 而不是 post.comments.create(...))。

post.comments.size - 这作为前两个的组合
选项。如果集合已经被加载,它将返回它的集合
length 就像调用 #length 一样。如果尚未加载,则为
就像调用 #count 一样。

我还有一个亲身经历:

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

I found a good answare at http://blog.hasmanythrough.com/2008/2/27/count-length-size

In ActiveRecord, there are several ways to find out how many records
are in an association, and there are some subtle differences in how
they work.

post.comments.count - Determine the number of elements with an SQL
COUNT query. You can also specify conditions to count only a subset of
the associated elements (e.g. :conditions => {:author_name =>
"josh"}). If you set up a counter cache on the association, #count
will return that cached value instead of executing a new query.

post.comments.length - This always loads the contents of the
association into memory, then returns the number of elements loaded.
Note that this won't force an update if the association had been
previously loaded and then new comments were created through another
way (e.g. Comment.create(...) instead of post.comments.create(...)).

post.comments.size - This works as a combination of the two previous
options. If the collection has already been loaded, it will return its
length just like calling #length. If it hasn't been loaded yet, it's
like calling #count.

Also I have a personal experience:

<%= h(params.size.to_s) %> # works_like_that !
<%= h(params.count.to_s) %> # does_not_work_like_that !
一枫情书 2024-10-16 16:09:02

我们有几种方法可以找出数组中有多少个元素,例如 .length.count.size。然而,最好使用array.size而不是array.count。因为.size在性能上比较好。

We have a several ways to find out how many elements in an array like .length, .count and .size. However, It's better to use array.size rather than array.count. Because .size is better in performance.

余罪 2024-10-16 16:09:02

在马克·拜尔斯的回答中添加更多内容。在 Ruby 中,方法 array.sizeArray#length 的别名方法。使用这两种方法中的任何一种都没有技术差异。也许您也不会看到性能有任何差异。但是,array.count 也可以完成相同的工作,但具有一些额外的功能Array# count

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

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

Array#count n # 返回 Array 中值为 n 的元素数量

Array #计数{|我| i.even?} 根据每个元素数组上调用的条件返回计数

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

这里所有三个方法都执行相同的工作。然而,这里的计数变得有趣。

比方说,我想找出该数组包含多少个值为 2 的数组元素。

array.count 2    # => 3

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

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

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

该数组共有 6 个元素,其中 >比 4.

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

Adding more to Mark Byers answer. In Ruby the method array.size is an alias to Array#length method. There is no technical difference in using any of these two methods. Possibly you won't see any difference in performance as well. However, the array.count also does the same job but with some extra functionalities Array#count

It can be used to get total no of elements based on some condition. Count can be called in three ways:

Array#count # Returns number of elements in Array

Array#count n # Returns number of elements having value n in Array

Array#count{|i| i.even?} Returns count based on condition invoked on each element array

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

Here all three methods do the same job. However here is where the count gets interesting.

Let us say, I want to find how many array elements does the array contains with value 2

array.count 2    # => 3

The array has a total of three elements with value as 2.

Now, I want to find all the array elements greater than 4

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

The array has total 6 elements which are > than 4.

I hope it gives some info about count method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文