Set class and repetetive elements

Hi,
I would like to know if there is possibility to add values like but have
a few elemens with the same value:

irb(main):002:0> require 'set'
=> true
irb(main):003:0> a = Set.new
=> #<Set: {}>
irb(main):004:0> a.add(1)
=> #<Set: {1}>
irb(main):005:0> a.add(1)
=> #<Set: {1}>
irb(main):006:0> a.add(1)
=> #<Set: {1}>
irb(main):007:0> a.add(2)
=> #<Set: {1, 2}>
irb(main):008:0> a.add(3)
=> #<Set: {1, 2, 3}>
irb(main):009:0> a.add(4)
=> #<Set: {1, 2, 3, 4}>
irb(main):010:0> a.add(5)
=> #<Set: {5, 1, 2, 3, 4}>
irb(main):011:0> a.add(6)
=> #<Set: {5, 6, 1, 2, 3, 4}>
irb(main):012:0> a.add(1)
=> #<Set: {5, 6, 1, 2, 3, 4}>

It would be nice to have for example {5, 1, 1, 1} in Set class object.
Is it possible? Which method should I use to add element in that way?

···

--
Posted via http://www.ruby-forum.com/.

Sounds like you want a Bag, not a Set. I don't know of aany implementation but
it's probably not hard to create one - all you have to do is keep track of the
count of each element.

···

On Tue, Jul 28, 2009 at 03:21:38AM +0900, Marcin Grski wrote:

It would be nice to have for example {5, 1, 1, 1} in Set class object.
Is it possible? Which method should I use to add element in that way?

--
Jos Backus
jos at catnook.com

Good Day Marcin,

···

2009/7/27 Marcin Górski <agormar@gmail.com>

Hi,
....

It would be nice to have for example {5, 1, 1, 1} in Set class object.
Is it possible? Which method should I use to add element in that way?

From ruby-doc.org

"Set <http://ruby-doc.org/core/classes/Set.html> implements a collection of
unordered values with no duplicates."

Is their some reason that an Array doesn't meet your needs? What does Set
bring to the table that Array would be missing for you?

John

Marcin Górski wrote:

Hi,
I would like to know if there is possibility to add values like but have
a few elemens with the same value:

irb(main):002:0> require 'set'
=> true
irb(main):003:0> a = Set.new
=> #<Set: {}>
irb(main):004:0> a.add(1)
=> #<Set: {1}>
irb(main):005:0> a.add(1)
=> #<Set: {1}>
irb(main):006:0> a.add(1)
=> #<Set: {1}>
irb(main):007:0> a.add(2)
=> #<Set: {1, 2}>
irb(main):008:0> a.add(3)
=> #<Set: {1, 2, 3}>
irb(main):009:0> a.add(4)
=> #<Set: {1, 2, 3, 4}>
irb(main):010:0> a.add(5)
=> #<Set: {5, 1, 2, 3, 4}>
irb(main):011:0> a.add(6)
=> #<Set: {5, 6, 1, 2, 3, 4}>
irb(main):012:0> a.add(1)
=> #<Set: {5, 6, 1, 2, 3, 4}>

It would be nice to have for example {5, 1, 1, 1} in Set class object.
Is it possible? Which method should I use to add element in that way?

You can build something based on hashes (Set is itself based on Hash):

class Bag
   def initialize
     @h = {}
   end
   def add val
     (@h[val] ||= []) << val
   end
   def [](key)
     @h[key]
   end
   def inspect
     "#<Bag: #{@h.values.inspect}>"
   end
end

bag = Bag.new

bag.add 1

bag.add 2

bag.add 3

p bag # ==> #<Bag: [[1, 1, 1], [2, 2], [3]]>

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Jos Backus wrote:

Sounds like you want a Bag, not a Set. I don't know of aany
implementation but
it's probably not hard to create one - all you have to do is keep track
of the
count of each element.

I've just read that elements in Set must be unique (because of Math). So
I'm going to solve my problem using arrays. Thanks for answer.

···

--
Posted via http://www.ruby-forum.com/.

What about using a Hash mapping objects to counts? That way you can
still do efficient lookups whether something is contained in the Bag.

A simple implementation could look like this:

  class Bag < Hash
    def initialize(*contents)
      super 0
      contents.each {|item|
        self[item] += 1
      }
    end

    def each
      return enum_for(__method__) unless block_given?

      each_pair {|item, count|
        count.times { yield item }
      }
    end

    def to_a
      each.to_a
    end
  end

cu,
Thomas

···

2009/7/27 Jos Backus <jos@catnook.com>:

On Tue, Jul 28, 2009 at 03:21:38AM +0900, Marcin Grski wrote:

It would be nice to have for example {5, 1, 1, 1} in Set class object.
Is it possible? Which method should I use to add element in that way?

Sounds like you want a Bag, not a Set. I don't know of aany implementation but
it's probably not hard to create one - all you have to do is keep track of the
count of each element.

--
When C++ is your hammer, every problem looks like your thumb.

Is their some reason that an Array doesn't meet your needs? What does
Set
bring to the table that Array would be missing for you?

John

Well I need to compare arrays which contain digits (or letters in
another program). If I use set it is easy to compare two sets which have
the same, unique elements in random order for example 1233 and 3321
should be equal. If I use set I will get wrong result for 1332 and 2213
– it shouldn't be equal. However, the array might contain elements with
the same value and it is what I neeed.

Solution is quite simple: I don't need Set. If I sort arrays I can
compare them easily (for numbers). Thanks for Bag solutions, it's quite
interesting and I may need it in future.

Thank you for your answers,

···

--
Posted via http://www.ruby-forum.com/.