-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkeyedArray.lua
More file actions
150 lines (130 loc) · 4.99 KB
/
keyedArray.lua
File metadata and controls
150 lines (130 loc) · 4.99 KB
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
-- Keyed arrays allow you to index items by their keys and positions in an array
-- The array starts at 1, just like normal Lua arrays
-- Keys are used to differentiate each item inside the keyed array
-- Possible key types are "array" and "table"
local KeyedArray = {}
--- Creates a new KeyedArray object.
-- @return (table) A KeyedArray object
function KeyedArray:new ()
-- Create a table to store the array elements
local obj = {
array = {}, -- Holds values that are indexed by position
table = {}, -- Holds values that are indexed with a key
}
-- Copies the method references into the object
for k, v in pairs (self) do
if type(v) == "function" and k ~= "new" then
obj[k] = v
end
end
return obj
end
--- Inserts a new item into the keyed array.
-- It will fail if an item already exists at the given key
-- @param key (table key) The key of the new item
-- @param value (any) The value of the new item
-- @param position (int) The position of the item in the array. Defaults to the current size of the array + 1 and will fix values outside the array bounds
-- @return (bool) True if the operation was successful, otherwise false
function KeyedArray:insert (key, value, position)
position = position or #self.array + 1
position = math.min (math.max (position, 1), #self.array + 1)
if self.table[key] == nil then
local container = {key = key, position = position, value = value} -- Values are placed in a container to avoid duplication
self.table[key] = container
table.insert (self.array, position, container)
-- Modify the position of all items after the inserted item
for i = position + 1, #self.array do
self.array[i].position = self.array[i].position + 1
end
return true
else
return false
end
end
--- Removes an item from the keyed array.
-- @raise When the provided keyType is invalid
-- @param key (table key) The key or position of the item
-- @param indexType (string) The type of index being used (either "array" or "key")
function KeyedArray:delete (key, indexType)
if indexType == "array" then
if self.array[key] ~= nil then
local container = self.array[key]
table.remove (self.array, container.position)
self.table[container.key] = nil
-- Modify the position of all items after the removed item
for i = container.position, #self.array do
self.array[i].position = self.array[i].position - 1
end
end
elseif indexType == "key" then
if self.table[key] ~= nil then
local container = self.table[key]
table.remove (self.array, container.position)
self.table[container.key] = nil
-- Modify the position of all items after the removed item
for i = container.position, #self.array do
self.array[i].position = self.array[i].position - 1
end
end
else
error ("KeyedArray: undefined key type")
end
end
--- Gets the value of an item from the keyed array.
-- @raise When the provided keyType is invalid
-- @param key (table key) The key or position of the item
-- @param indexType (string) The type of index being used (either "array" or "key")
function KeyedArray:get (key, indexType)
if indexType == "array" then
if self.array[key] == nil then
return nil
else
return self.array[key].value
end
elseif indexType == "key" then
if self.table[key] == nil then
return nil
else
return self.table[key].value
end
else
error ("KeyedArray: undefined key type")
end
end
--- Gets the current number of items inside the object.
-- @return (int) The number of items inside the object
function KeyedArray:size ()
return #self.array
end
--- An iterator function for the keyed array object.
-- This will iterate over the items based on their order in the array
-- @usage for pos, key, value in KeyedArrayObj:pairs () do print (value) end
-- @return (function) An iterator function
function KeyedArray:pairs ()
local index = 0
return function ()
index = index + 1
if index <= #self.array then
return self.array[index].position, self.array[index].key, self.array[index].value
end
end
end
--- Gets the corresponding key or array index for a value.
-- @param key (table key) The key or position of the item
-- @param indexType (string) The type of index being used (either "array" or "key")
function KeyedArray:getKey(key, indexType)
if indexType == "array" then
if self.array[key] ~= nil then
local container = self.array[key]
return container.key
end
elseif indexType == "key" then
if self.table[key] ~= nil then
local container = self.table[key]
return container.position
end
else
error("KeyedArray: undefined key type")
end
end
return KeyedArray