Multisets and Bags in Ruby

I’ve been looking around for an implementation of a Multiset/Bag in Ruby to ease the pain of recording some of our statistics.

Some of the statistics we gather are most usefully stored as some form of “super” Set in which each unique element is stored together with a count of the number of times that element has occurred. These statistics are likely to have a large number of repeated elements, so this makes sense as it saves on space and processing.

So, after an extensive search, I was surprised at the paucity of solutions for this problem.

Eventually I hit upon

http://maraigue.hhiro.net/multiset/index-en.php

It does exactly what I want, but I decided that I would add the following custom functions. These two functions return all the items in a Multiset with the highest/lowest counts.

class Multiset
  # Return all the items with the maximum count
  def max_values
    max_value = @items.values.max
    @items.select { |k, v| v == max_value }.map { |i| i[0] }
  end

  # Return all the items with the minimum count
  def min_values
    min_value = @items.values.min
    @items.select { |k, v| v == min_value }.map { |i| i[0] }
  end
end