本文介绍了Enumerable的group_by是否保留Enumerable的顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Enumerable#group_by 是否保留每个值内的原始顺序?当我得到这个:

Does Enumerable#group_by preserve the original order within each value? When I get this:

[1, 2, 3, 4, 5].group_by{|i| i % 2}
# => {1=>[1, 3, 5], 0=>[2, 4]}

是否保证例如数组[1, 3, 5]按此顺序包含元素,而不是例如[3, 1, 5]?

is it guaranteed that, for example, the array [1, 3, 5] contains the elements in this order and not, for example [3, 1, 5]?

关于这一点有什么描述吗?

Is there any description regarding this point?

我没有提到按键10之间的顺序.那是另一个问题.

I am not mentioning the order between the keys 1 and 0. That is a different issue.

推荐答案

是的,Enumerable#group_by保留输入顺序.

这是MRI中该方法的实现,来自 https://github.com. com/ruby​​/ruby​​/blob/trunk/enum.c :

Here's the implementation of that method in MRI, from https://github.com/ruby/ruby/blob/trunk/enum.c:

static VALUE
enum_group_by(VALUE obj)
{
    VALUE hash;

    RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size);

    hash = rb_hash_new();
    rb_block_call(obj, id_each, 0, 0, group_by_i, hash);
    OBJ_INFECT(hash, obj);

    return hash;
}

static VALUE
group_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, hash))
{
    VALUE group;
    VALUE values;

    ENUM_WANT_SVALUE();

    group = rb_yield(i);
    values = rb_hash_aref(hash, group);
    if (!RB_TYPE_P(values, T_ARRAY)) {
        values = rb_ary_new3(1, i);
        rb_hash_aset(hash, group, values);
    }
    else {
        rb_ary_push(values, i);
    }
    return Qnil;
}

enum_group_by依次在每个数组(obj)元素上调用group_by_i. group_by_i第一次遇到一个组时会创建一个单元素数组(rb_ary_new3(1, i)),然后将其推入数组(rb_ary_push(values, i)).这样就保留了输入顺序.

enum_group_by calls group_by_i on each array (obj) element in order. group_by_i creates a one-element array (rb_ary_new3(1, i)) the first time a group is encountered, and pushes on to the array thereafter (rb_ary_push(values, i)). So the input order is preserved.

此外,RubySpec也需要它.来自 https://github.com/rubyspec/rubyspec/blob/master/core/enumerable/group_by_spec.rb :

Also, RubySpec requires it. From https://github.com/rubyspec/rubyspec/blob/master/core/enumerable/group_by_spec.rb:

it "returns a hash with values grouped according to the block" do
  e = EnumerableSpecs::Numerous.new("foo", "bar", "baz")
  h = e.group_by { |word| word[0..0].to_sym }
  h.should == { :f => ["foo"], :b => ["bar", "baz"]}
end

这篇关于Enumerable的group_by是否保留Enumerable的顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 02:09