Skip to content

Commit 2da215d

Browse files
authored
Merge pull request #234 from JaapWijnen/master
Updated Ordered Set to swift 3
2 parents ebbfe7b + a6bff78 commit 2da215d

File tree

9 files changed

+66
-39
lines changed

9 files changed

+66
-39
lines changed

Diff for: Ordered Set/OrderedSet.playground/Pages/Example 1.xcplaygroundpage/Contents.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ var mySet = OrderedSet<Int>()
44

55
// Insert random numbers into the set
66
for _ in 0..<50 {
7-
mySet.insert(random(50, max: 500))
7+
mySet.insert(random(min: 50, max: 500))
88
}
99

1010
print(mySet)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Timeline
3+
version = "3.0">
4+
<TimelineItems>
5+
<LoggerValueHistoryTimelineItem
6+
documentLocation = "#CharacterRangeLen=21&amp;CharacterRangeLoc=288&amp;EndingColumnNumber=22&amp;EndingLineNumber=18&amp;StartingColumnNumber=1&amp;StartingLineNumber=18&amp;Timestamp=496197876.557751"
7+
selectedRepresentationIndex = "0"
8+
shouldTrackSuperviewWidth = "NO">
9+
</LoggerValueHistoryTimelineItem>
10+
<LoggerValueHistoryTimelineItem
11+
documentLocation = "#CharacterRangeLen=24&amp;CharacterRangeLoc=329&amp;EndingColumnNumber=27&amp;EndingLineNumber=20&amp;StartingColumnNumber=3&amp;StartingLineNumber=20&amp;Timestamp=496197876.557751"
12+
selectedRepresentationIndex = "0"
13+
shouldTrackSuperviewWidth = "NO">
14+
</LoggerValueHistoryTimelineItem>
15+
<LoggerValueHistoryTimelineItem
16+
documentLocation = "#CharacterRangeLen=25&amp;CharacterRangeLoc=428&amp;EndingColumnNumber=28&amp;EndingLineNumber=26&amp;StartingColumnNumber=3&amp;StartingLineNumber=26&amp;Timestamp=496197876.557751"
17+
selectedRepresentationIndex = "0"
18+
shouldTrackSuperviewWidth = "NO">
19+
</LoggerValueHistoryTimelineItem>
20+
</TimelineItems>
21+
</Timeline>

Diff for: Ordered Set/OrderedSet.playground/Pages/Example 2.xcplaygroundpage/Contents.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ print(playerSet.max())
2323
print(playerSet.min())
2424

2525
// We'll find our player now:
26-
let level = playerSet.count - playerSet.indexOf(anotherPlayer)!
26+
let level = playerSet.count - playerSet.index(of: anotherPlayer)!
2727
print("\(anotherPlayer.name) is ranked at level \(level) with \(anotherPlayer.points) points")
2828

2929
//: [Next](@next)

Diff for: Ordered Set/OrderedSet.playground/Pages/Example 3.xcplaygroundpage/Contents.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ repeatedSet.insert(Player(name: "Player 9", points: 25))
1717
print(repeatedSet)
1818
//debugPrint(repeatedSet)
1919

20-
print(repeatedSet.indexOf(Player(name: "Player 5", points: 100)))
21-
print(repeatedSet.indexOf(Player(name: "Random Player", points: 100)))
22-
print(repeatedSet.indexOf(Player(name: "Player 5", points: 1000)))
20+
print(repeatedSet.index(of: Player(name: "Player 5", points: 100)))
21+
print(repeatedSet.index(of: Player(name: "Random Player", points: 100)))
22+
print(repeatedSet.index(of: Player(name: "Player 5", points: 1000)))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Timeline
3+
version = "3.0">
4+
<TimelineItems>
5+
</TimelineItems>
6+
</Timeline>

Diff for: Ordered Set/OrderedSet.playground/Sources/OrderedSet.swift

+12-12
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ public struct OrderedSet<T: Comparable> {
1414
}
1515

1616
// Inserts an item. Performance: O(n)
17-
public mutating func insert(item: T) {
17+
public mutating func insert(_ item: T) {
1818
if exists(item) {
1919
return // don't add an item if it already exists
2020
}
2121

2222
// Insert new the item just before the one that is larger.
2323
for i in 0..<count {
2424
if internalSet[i] > item {
25-
internalSet.insert(item, atIndex: i)
25+
internalSet.insert(item, at: i)
2626
return
2727
}
2828
}
@@ -32,19 +32,19 @@ public struct OrderedSet<T: Comparable> {
3232
}
3333

3434
// Removes an item if it exists. Performance: O(n)
35-
public mutating func remove(item: T) {
36-
if let index = indexOf(item) {
37-
internalSet.removeAtIndex(index)
35+
public mutating func remove(_ item: T) {
36+
if let index = index(of: item) {
37+
internalSet.remove(at: index)
3838
}
3939
}
4040

4141
// Returns true if and only if the item exists somewhere in the set.
42-
public func exists(item: T) -> Bool {
43-
return indexOf(item) != nil
42+
public func exists(_ item: T) -> Bool {
43+
return index(of: item) != nil
4444
}
4545

4646
// Returns the index of an item if it exists, or -1 otherwise.
47-
public func indexOf(item: T) -> Int? {
47+
public func index(of item: T) -> Int? {
4848
var leftBound = 0
4949
var rightBound = count - 1
5050

@@ -64,7 +64,7 @@ public struct OrderedSet<T: Comparable> {
6464
// and to the left in order to find an exact match.
6565

6666
// Check to the right.
67-
for j in mid.stride(to: count - 1, by: 1) {
67+
for j in stride(from: mid, to: count - 1, by: 1) {
6868
if internalSet[j + 1] == item {
6969
return j + 1
7070
} else if internalSet[j] < internalSet[j + 1] {
@@ -73,7 +73,7 @@ public struct OrderedSet<T: Comparable> {
7373
}
7474

7575
// Check to the left.
76-
for j in mid.stride(to: 0, by: -1) {
76+
for j in stride(from: mid, to: 0, by: -1) {
7777
if internalSet[j - 1] == item {
7878
return j - 1
7979
} else if internalSet[j] > internalSet[j - 1] {
@@ -105,13 +105,13 @@ public struct OrderedSet<T: Comparable> {
105105

106106
// Returns the k-th largest element in the set, if k is in the range
107107
// [1, count]. Returns nil otherwise.
108-
public func kLargest(k: Int) -> T? {
108+
public func kLargest(_ k: Int) -> T? {
109109
return k > count || k <= 0 ? nil : internalSet[count - k]
110110
}
111111

112112
// Returns the k-th smallest element in the set, if k is in the range
113113
// [1, count]. Returns nil otherwise.
114-
public func kSmallest(k: Int) -> T? {
114+
public func kSmallest(_ k: Int) -> T? {
115115
return k > count || k <= 0 ? nil : internalSet[k - 1]
116116
}
117117
}

Diff for: Ordered Set/OrderedSet.playground/Sources/Player.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public struct Player: Comparable {
66

77
public init() {
88
self.name = String.random()
9-
self.points = random(0, max: 5000)
9+
self.points = random(min: 0, max: 5000)
1010
}
1111

1212
public init(name: String, points: Int) {

Diff for: Ordered Set/OrderedSet.playground/Sources/Random.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extension String {
1313

1414
for _ in 0..<length {
1515
let randomValue = arc4random_uniform(UInt32(base.characters.count))
16-
randomString += "\(base[base.startIndex.advancedBy(Int(randomValue))])"
16+
randomString += "\(base[base.index(base.startIndex, offsetBy: Int(randomValue))])"
1717
}
1818
return randomString
1919
}

Diff for: Ordered Set/README.markdown

+20-20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Ordered Set
22

3-
An Ordered Set is a collection of unique items in sorted order. Items are usually sorted from least to greatest.
3+
An Ordered Set is a collection of unique items in sorted order. Items are usually sorted from least to greatest.
44

55
The Ordered Set data type is a hybrid of:
66

@@ -11,7 +11,7 @@ It's important to keep in mind that two items can have the same *value* but stil
1111

1212
## Why use an ordered set?
1313

14-
Ordered Sets should be considered when you need to keep your collection sorted at all times, and you do lookups on the collection much more frequently than inserting or deleting items. Many of the lookup operations for an Ordered Set are **O(1)**.
14+
Ordered Sets should be considered when you need to keep your collection sorted at all times, and you do lookups on the collection much more frequently than inserting or deleting items. Many of the lookup operations for an Ordered Set are **O(1)**.
1515

1616
A good example would be keeping track of the rankings of players in a scoreboard (see example 2 below).
1717

@@ -55,15 +55,15 @@ public struct OrderedSet<T: Comparable> {
5555
Lets take a look at the `insert()` function first. This first checks if the item already exists in the collection. If so, it returns and does not insert the item. Otherwise, it will insert the item through straightforward iteration.
5656

5757
```swift
58-
public mutating func insert(item: T){
58+
public mutating func insert(_ item: T){
5959
if exists(item) {
6060
return // don't add an item if it already exists
6161
}
6262

6363
// Insert new the item just before the one that is larger.
6464
for i in 0..<count {
6565
if internalSet[i] > item {
66-
internalSet.insert(item, atIndex: i)
66+
internalSet.insert(item, at: i)
6767
return
6868
}
6969
}
@@ -82,19 +82,19 @@ The total performance of the `insert()` function is therefore **O(n)**.
8282
Next up is the `remove()` function:
8383

8484
```swift
85-
public mutating func remove(item: T) {
86-
if let index = indexOf(item) {
87-
internalSet.removeAtIndex(index)
85+
public mutating func remove(_ item: T) {
86+
if let index = index(of: item) {
87+
internalSet.remove(at: index)
8888
}
8989
}
9090
```
9191

9292
First this checks if the item exists and then removes it from the array. Because of the `removeAtIndex()` function, the efficiency for remove is **O(n)**.
9393

94-
The next function is `indexOf()`, which takes in an object of type `T` and returns the index of the corresponding item if it is in the set, or `nil` if it is not. Since our set is sorted, we can use a binary search to quickly search for the item.
94+
The next function is `indexOf()`, which takes in an object of type `T` and returns the index of the corresponding item if it is in the set, or `nil` if it is not. Since our set is sorted, we can use a binary search to quickly search for the item.
9595

9696
```swift
97-
public func indexOf(item: T) -> Int? {
97+
public func index(of item: T) -> Int? {
9898
var leftBound = 0
9999
var rightBound = count - 1
100100

@@ -115,9 +115,9 @@ The next function is `indexOf()`, which takes in an object of type `T` and retur
115115
}
116116
```
117117

118-
> **Note:** If you are not familiar with the concept of binary search, we have an [article that explains all about it](../Binary Search).
118+
> **Note:** If you are not familiar with the concept of binary search, we have an [article that explains all about it](../Binary Search).
119119

120-
However, there is an important issue to deal with here. Recall that two objects can be unequal yet still have the same "value" for the purposes of comparing them. Since a set can contain multiple items with the same value, it is important to check that the binary search has landed on the correct item.
120+
However, there is an important issue to deal with here. Recall that two objects can be unequal yet still have the same "value" for the purposes of comparing them. Since a set can contain multiple items with the same value, it is important to check that the binary search has landed on the correct item.
121121

122122
For example, consider this ordered set of `Player` objects. Each `Player` has a name and a number of points:
123123

@@ -147,13 +147,13 @@ Therefore, we also need to check the items with the same value to the right and
147147
break
148148
}
149149
}
150-
150+
151151
return nil
152152
```
153153

154154
These loops start at the current `mid` value and then look at the neighboring values until we've found the correct object.
155155

156-
The combined runtime for `indexOf()` is **O(log(n) + k)** where **n** is the length of the set, and **k** is the number of items with the same *value* as the one that is being searched for.
156+
The combined runtime for `indexOf()` is **O(log(n) + k)** where **n** is the length of the set, and **k** is the number of items with the same *value* as the one that is being searched for.
157157

158158
Since the set is sorted, the following operations are all **O(1)**:
159159

@@ -168,15 +168,15 @@ Since the set is sorted, the following operations are all **O(1)**:
168168
return count == 0 ? nil : internalSet[0]
169169
}
170170

171-
// Returns the k-th largest element in the set, if k is in the range
171+
// Returns the k-th largest element in the set, if k is in the range
172172
// [1, count]. Returns nil otherwise.
173-
public func kLargest(k: Int) -> T? {
173+
public func kLargest(_ k: Int) -> T? {
174174
return k > count || k <= 0 ? nil : internalSet[count - k]
175175
}
176176

177177
// Returns the k-th smallest element in the set, if k is in the range
178178
// [1, count]. Returns nil otherwise.
179-
public func kSmallest(k: Int) -> T? {
179+
public func kSmallest(_ k: Int) -> T? {
180180
return k > count || k <= 0 ? nil : internalSet[k - 1]
181181
}
182182
```
@@ -228,7 +228,7 @@ public struct Player: Comparable {
228228
The `Player` also gets its own `==` and `<` operators. The `<` operator is used to determine the sort order of the set, while `==` determines whether two objects are really equal.
229229

230230
Note that `==` compares both the name and the points:
231-
231+
232232
```swifr
233233
func ==(x: Player, y: Player) -> Bool {
234234
return x.name == y.name && x.points == y.points
@@ -272,7 +272,7 @@ print("\(anotherPlayer.name) is ranked at level \(level) with \(anotherPlayer.po
272272

273273
### Example 3
274274

275-
The final example demonstrates the need to look for the right item even after the binary search has completed.
275+
The final example demonstrates the need to look for the right item even after the binary search has completed.
276276

277277
We insert 9 players into the set:
278278

@@ -299,7 +299,7 @@ The set looks something like this:
299299
The next line looks for `Player 2`:
300300

301301
```swift
302-
print(repeatedSet.indexOf(Player(name: "Player 2", points: 100)))
302+
print(repeatedSet.index(of: Player(name: "Player 2", points: 100)))
303303
```
304304

305305
After the binary search finishes, the value of `mid` is at index 5:
@@ -312,7 +312,7 @@ However, this is not `Player 2`. Both `Player 4` and `Player 2` have the same po
312312
But we do know that `Player 2` must be either to the immediate left or the right of `Player 4`, so we check both sides of `mid`. We only need to look at the objects with the same value as `Player 4`. The others are replaced by `X`:
313313

314314
[X, X, Player 1, Player 2, Player 3, Player 4, Player 5, X, X]
315-
mid
315+
mid
316316

317317
The code then first checks on the right of `mid` (where the `*` is):
318318

0 commit comments

Comments
 (0)