红宝石:想要一个集合类对象,preserves秩序 [英] Ruby: Want a Set-like object which preserves order

查看:136
本文介绍了红宝石:想要一个集合类对象,preserves秩序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

...或替代其中prevents重复项的Array。

... or alternatively an Array which prevents duplicate entries.

是否有某种Ruby中其中的对象:


  • 响应[],[] =和<<

  • 默默滴重复的条目
  • 可枚举(或至少支持find_all)
  • preserves在哪些条目已插入的顺序

    Is there some kind of object in Ruby which:

    • responds to [], []= and <<
    • silently drops duplicate entries
    • is Enumerable (or at least supports find_all)
    • preserves the order in which entries were inserted

      据我所知,一个阵列支持要点1,3和4;而一组支持1,2和3(而不是4)。而如果SortedSet不会做,因为我的作品没有实现&LT; =>

      As far as I can tell, an Array supports points 1, 3 and 4; while a Set supports 1, 2 and 3 (but not 4). And a SortedSet won't do, because my entries don't implement <=>.

      推荐答案

      没有一个,据我所知,并由其数学性质设置是为了是无序的(或至少,implementationally,并不是为了保障为了 - 事实上它通常被实现为一个哈希表,因此不弄乱顺序)

      There isn't one as far as I know, and Set by its mathematical nature is meant to be unordered (or at least, implementationally, meant not to guarantee order - in fact its usually implemented as a hash table so it does mess up order).

      然而,这并不难直接延长数组或继承它做到这一点。我只是想出来,这个作品:

      However, it's not hard to either extend array directly or subclass it to do this. I just tried it out and this works:

      class UniqueArray < Array
        def initialize(*args)
          if args.size == 1 and args[0].is_a? Array then
            super(args[0].uniq)
          else
            super(*args)
          end
        end
      
        def insert(i, v)
          super(i, v) unless include?(v)
        end
      
        def <<(v)
          super(v) unless include?(v)
        end
      
        def []=(*args)
          # note: could just call super(*args) then uniq!, but this is faster
      
          # there are three different versions of this call:
          # 1. start, length, value
          # 2. index, value
          # 3. range, value
          # We just need to get the value
          v = case args.size
            when 3 then args[2]
            when 2 then args[1]
            else nil
          end
      
          super(*args) if v.nil? or not include?(v)
        end
      end
      

      似乎涵盖所有的基础。我用奥莱利的得心应手红宝石食谱作为参考 - 他们有一个确保一个有序数组排序保持,这是类似配方

      Seems to cover all the bases. I used OReilly's handy Ruby Cookbook as a reference - they have a recipe for "Making sure a sorted array stays sorted" which is similar.

      这篇关于红宝石:想要一个集合类对象,preserves秩序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆