Set class and repetetive elements

M

Marcin Górski

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?
 
J

Jos Backus

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

Marcin Górski

Jos said:
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.
 
J

John W Higgins

Good Day Marcin,

2009/7/27 Marcin G=F3rski said:
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
 
J

Joel VanderWerf

Marcin said:
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 1
bag.add 1

bag.add 2
bag.add 2

bag.add 3

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

Thomas Chust

2009/7/27 Jos Backus said:
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
 
M

Marcin Górski

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,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top