# Set class and repetetive elements

**URL:** <https://www.ruby-forum.com/t/set-class-and-repetetive-elements/172770>\
**Category:** Ruby\
**Created:** [July 27, 2009, 8:21pm UTC](https://www.ruby-forum.com/t/set-class-and-repetetive-elements/172770 "2009-07-27T20:21:31Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![asmo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ea666f/32.png) [@asmo](https://www.ruby-forum.com/u/asmo)\
**Post date:** [July 27, 2009, 8:21pm UTC](https://www.ruby-forum.com/t/set-class-and-repetetive-elements/172770/1 "2009-07-27T20:21:31Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![asmo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ea666f/32.png) [@asmo](https://www.ruby-forum.com/u/asmo)\
**Post date:** [July 27, 2009, 8:30pm UTC](https://www.ruby-forum.com/t/set-class-and-repetetive-elements/172770/2 "2009-07-27T20:30:49Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![asmo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ea666f/32.png) [@asmo](https://www.ruby-forum.com/u/asmo)\
**Post date:** [July 27, 2009, 8:38pm UTC](https://www.ruby-forum.com/t/set-class-and-repetetive-elements/172770/3 "2009-07-27T20:38:08Z")

</div>

Jos B. 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.

---

<div class="post-metadata">

**Author:** ![asmo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ea666f/32.png) [@asmo](https://www.ruby-forum.com/u/asmo)\
**Post date:** [July 27, 2009, 8:40pm UTC](https://www.ruby-forum.com/t/set-class-and-repetetive-elements/172770/4 "2009-07-27T20:40:46Z")

</div>

Good Day Marcin,

2009/7/27 Marcin GÃ³rski [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> 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](http://ruby-doc.org)

“Set [http://ruby-doc.org/core/classes/Set.html](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

---

<div class="post-metadata">

**Author:** ![asmo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ea666f/32.png) [@asmo](https://www.ruby-forum.com/u/asmo)\
**Post date:** [July 27, 2009, 9:11pm UTC](https://www.ruby-forum.com/t/set-class-and-repetetive-elements/172770/5 "2009-07-27T21:11:48Z")

</div>

2009/7/27 Jos B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> 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.

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

---

<div class="post-metadata">

**Author:** ![asmo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ea666f/32.png) [@asmo](https://www.ruby-forum.com/u/asmo)\
**Post date:** [July 27, 2009, 9:05pm UTC](https://www.ruby-forum.com/t/set-class-and-repetetive-elements/172770/6 "2009-07-27T21:05:57Z")

</div>

Marcin GÃ³rski wrote:

> irb(main):005:0\> a.add(1)  
> =\> #\<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   
@h[key]  
end  
def inspect  
“#\<Bag: #{@h.values.inspect}\>”  
end  
end

bag = Bag.new

bag.add 1  
bag.add 1  
bag.add 1

bag.add 2  
bag.add 2

bag.add 3

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

---

<div class="post-metadata">

**Author:** ![asmo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ea666f/32.png) [@asmo](https://www.ruby-forum.com/u/asmo)\
**Post date:** [July 27, 2009, 9:23pm UTC](https://www.ruby-forum.com/t/set-class-and-repetetive-elements/172770/7 "2009-07-27T21:23:52Z")

</div>

> 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,
