This repository has been archived by the owner on Jan 21, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
custom_set.rb
94 lines (73 loc) · 1.7 KB
/
custom_set.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
class CustomSet
include Enumerable
attr_reader :members
# Argument value must be enumerable, which will always have a to_a method
# if it's nil then it also has a to_a method
def initialize(enum=[])
@members= enum.to_a.uniq.dup
end
def size
members.size
end
def each(&blk)
members.each(&blk)
end
# Since Ruby does type conversion and we need to treat 2.0 distinct from 2
#[1,2.0,2,3].index(2.0) #=> 1
#[1,2.0,2,3].index(2) #=> 1
# We need to modify with a block
def index(other)
members.index { |item| item.eql?(other) }
end
def ==(other)
return false unless other.class == self.class
return false unless other.size ==self.size
other.each do |item|
return false unless index(item)
end
true
end
def eql?(other)
self == other
end
def delete(item)
members.delete(item) if index(item)
self
end
def difference(other)
self.class.new(members - other.to_a)
end
def intersection(other)
self.class.new(members & other.to_a)
end
def union(other)
self.class.new(members | other.to_a)
end
def disjoint?(other)
union(other).size == self.size + other.size
end
def subset?(other)
self.size >= other.size && intersection(other) == other
end
def member?(n)
index(n)
end
def put(item)
members << item unless member?(item)
self
end
def empty!
self.members.clear
self
end
# you don't want to return your instance variable directly! If you do, it can then be modified externally.
def to_a
members.dup
end
def dup
self.class.new(members)
end
alias_method :|, :union
alias_method :&, :intersection
alias_method :-, :difference
end