【问题标题】:Does Ruby uniq preserve ordering?Ruby uniq 是否保留排序?
【发布时间】:2015-01-23 16:06:17
【问题描述】:

文档没有说明这一点 (http://www.ruby-doc.org/core-2.2.0/Array.html#method-i-uniq)。

另外,它是使用简单的 O(n^2) 搜索还是其他类似 hashmap 的东西?在后一种情况下,我是否应该理解我的元素必须正确实现 hasheql? 当我想统一它们时?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    给定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(complexity(ary_make_hash) + N),大概是 O(N)

    【讨论】:

    • 这很好,因为我需要保存每个唯一事件的第一个实例的顺序。即:{ 1,2,1,4,5,4,6,4 } => { 1,2,4,5,6 } 由于没有记录此“功能”,它会保持不变吗?
    • 从 ruby​​ 1.9 及更高版本开始保留哈希插入顺序。 Set 建立在散列之上。所以这将保持不变(有关更多信息,请参阅此 SO 问题stackoverflow.com/questions/773403/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 1970-01-01
    相关资源
    最近更新 更多