Ruby中是否存在自带的去重队列(Unique Queue)数据结构?
Ruby去重队列实现说明
原生支持情况
Ruby标准库没有内置现成的去重队列数据结构,不过可以通过Set和数组/Queue组合,快速实现符合需求的去重队列,包括自定义去重键的扩展需求。
基础版去重队列实现
仅基于元素本身的值做去重判断,重复元素入队直接被拦截:
require 'set' class UniqueQueue def initialize @queue = [] @seen = Set.new end # 入队操作,重复元素返回false,入队成功返回true def enqueue(item) return false if @seen.include?(item) @seen.add(item) @queue << item true end # 出队操作,返回队首元素 def dequeue item = @queue.shift @seen.delete(item) item end def empty? @queue.empty? end def size @queue.size end end
这个版本遵循标准队列FIFO规则,入队时自动校验元素是否已存在于队列中,存在则直接跳过入队操作。
支持自定义去重键的扩展实现
如果需要按自定义规则判断唯一性(比如按对象的某个属性、特定字段去重),可以在初始化时传入规则生成唯一键:
class CustomUniqueQueue def initialize(&key_generator) @queue = [] @seen = Set.new # 未传入规则时默认用元素本身作为唯一键 @key_generator = key_generator || ->(item) { item } end def enqueue(item) key = @key_generator.call(item) return false if @seen.include?(key) @seen.add(key) @queue << item true end def dequeue item = @queue.shift key = @key_generator.call(item) @seen.delete(key) item end def empty? @queue.empty? end def size @queue.size end end
使用示例:
# 按用户id去重,同一id的用户只入队一次 queue = CustomUniqueQueue.new { |user| user[:id] } queue.enqueue({id: 1, name: "张三"}) # => true queue.enqueue({id: 1, name: "张三更新后"}) # => false,id重复被拦截
常见场景调整
如果你的业务场景要求元素即使出队后,也不允许再次入队,可以删除dequeue方法中删除@seen集合键的逻辑,保证整个实例生命周期内同一规则的元素只会入队一次。
内容的提问来源于stack exchange,提问作者B Seven
相关产品推荐
相关产品推荐

