Ruby uniq是否保留了订购?

时间:2015-01-23 16:06:18

标签: ruby

文档没有说明任何内容(http://www.ruby-doc.org/core-2.2.0/Array.html#method-i-uniq)。

此外,它是使用天真的O(n ^ 2)搜索还是其他类似哈希映射的东西?在后一种情况下,我是否应该理解当我想要将它们统一化时,我的元素必须正确实现hasheql?

1 个答案:

答案 0 :(得分:18)

给出Array#uniq

的代码(在C中)
rb_ary_uniq(VALUE ary)
{
    VALUE hash, uniq, v;
    long i;

    if (RARRAY_LEN(ary) <= 1)
        return rb_ary_dup(ary);
    if (rb_block_given_p()) {
        hash = ary_make_hash_by(ary);
        uniq = ary_new(rb_obj_class(ary), RHASH_SIZE(hash));
        st_foreach(RHASH_TBL(hash), push_value, uniq);
    }
    else {
        hash = ary_make_hash(ary);
        uniq = ary_new(rb_obj_class(ary), RHASH_SIZE(hash));
        for (i=0; i<RARRAY_LEN(ary); i++) {
            st_data_t vv = (st_data_t)(v = rb_ary_elt(ary, i));
            if (st_delete(RHASH_TBL(hash), &vv, 0)) {
                rb_ary_push(uniq, v);
            }
        }
    }
    ary_recycle_hash(hash);

    return uniq;
}

在一般情况下(else块),它从数组创建一个哈希(在不保持顺序的情况下统一密钥)。然后它创建一个具有正确大小的新空数组。最后它通过第一个数组,当它在哈希中找到密钥时,删除该密钥并将其推送到空数组。

因此保留了订单。

我说复杂性是O(复杂度(ary_make_hash)+ N)及时,可能是O(N)