.../Source/Extensions/OrderedSet.swift
Line | Count | Source |
1 | | // |
2 | | // OrderedSet.swift |
3 | | // |
4 | | // Written By Kai Chen |
5 | | // https://github.com/raywenderlich/swift-algorithm-club/tree/master/Ordered%20Set |
6 | | // |
7 | | |
8 | | import Foundation |
9 | | |
10 | | public class OrderedSet<T: Hashable> { |
11 | | |
12 | 11 | public var count: Int { |
13 | 11 | return objects.count |
14 | 11 | } |
15 | | |
16 | 96 | private var objects: [T] = [] |
17 | 96 | private var indexOfKey: [T: Int] = [:] |
18 | | |
19 | 96 | public init() {} |
20 | | |
21 | 33 | public func add(_ object: T) { |
22 | 33 | guard indexOfKey[object] == nil else { |
23 | 1 | return |
24 | 32 | } |
25 | 32 | |
26 | 32 | objects.append(object) |
27 | 32 | indexOfKey[object] = objects.count - 1 |
28 | 32 | } |
29 | | |
30 | 9 | public func insert(_ object: T, at index: Int) { |
31 | 9 | assert(index < objects.count, "Index should be smaller than object count") |
32 | 9 | assert(index >= 0, "Index should be bigger than 0") |
33 | 9 | |
34 | 9 | guard indexOfKey[object] == nil else { |
35 | 2 | return |
36 | 7 | } |
37 | 7 | |
38 | 7 | objects.insert(object, at: index) |
39 | 7 | indexOfKey[object] = index |
40 | 7 | for idx in index + 1..<objects.count { |
41 | 6 | indexOfKey[objects[idx]] = idx |
42 | 7 | } |
43 | 7 | } |
44 | | |
45 | 6 | public func object(at index: Int) -> T { |
46 | 6 | assert(index < objects.count, "Index should be smaller than object count") |
47 | 6 | assert(index >= 0, "Index should be bigger than 0") |
48 | 6 | |
49 | 6 | return objects[index] |
50 | 6 | } |
51 | | |
52 | 4 | public func set(_ object: T, at index: Int) { |
53 | 4 | assert(index < objects.count, "Index should be smaller than object count") |
54 | 4 | assert(index >= 0, "Index should be bigger than 0") |
55 | 4 | |
56 | 4 | guard indexOfKey[object] == nil else { |
57 | 1 | return |
58 | 3 | } |
59 | 3 | |
60 | 3 | indexOfKey.removeValue(forKey: objects[index]) |
61 | 3 | indexOfKey[object] = index |
62 | 3 | objects[index] = object |
63 | 3 | } |
64 | | |
65 | 3 | public func indexOf(_ object: T) -> Int { |
66 | 3 | return indexOfKey[object] ?? -1 |
67 | 3 | } |
68 | | |
69 | 3 | public func remove(_ object: T) { |
70 | 3 | guard let index = indexOfKey[object] else { |
71 | 1 | return |
72 | 2 | } |
73 | 2 | |
74 | 2 | indexOfKey.removeValue(forKey: object) |
75 | 2 | objects.remove(at: index) |
76 | 2 | for idx in index..<objects.count { |
77 | 2 | indexOfKey[objects[idx]] = idx |
78 | 2 | } |
79 | 2 | } |
80 | | |
81 | 10 | public func all() -> [T] { |
82 | 10 | return objects |
83 | 10 | } |
84 | | } |