| 1 | --[[ |
|---|
| 2 | List class |
|---|
| 3 | =========== |
|---|
| 4 | |
|---|
| 5 | DESCRIPTION |
|---|
| 6 | ----------- |
|---|
| 7 | |
|---|
| 8 | リストを扱うクラス |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | SYNOPSYS |
|---|
| 12 | -------- |
|---|
| 13 | |
|---|
| 14 | l1 = List.new(1, 2, 3) |
|---|
| 15 | l2 = List.new(4, 5, 6) |
|---|
| 16 | l3 = l1 + l2 |
|---|
| 17 | |
|---|
| 18 | print(l1:join()) |
|---|
| 19 | print(l2:join("\n")) |
|---|
| 20 | print(l3:join(" ")) |
|---|
| 21 | |
|---|
| 22 | print(l3:map(function (i) |
|---|
| 23 | return i * i |
|---|
| 24 | end)) |
|---|
| 25 | ]] |
|---|
| 26 | |
|---|
| 27 | require "Class" |
|---|
| 28 | |
|---|
| 29 | List = Class { super = nil, |
|---|
| 30 | __tostring = function () |
|---|
| 31 | return "#<Class List>" |
|---|
| 32 | end, |
|---|
| 33 | |
|---|
| 34 | __add = function (op1, op2) |
|---|
| 35 | local ret = List.new() |
|---|
| 36 | op1:each(function (i) |
|---|
| 37 | ret:push(i) |
|---|
| 38 | end) |
|---|
| 39 | op2:each(function (i) |
|---|
| 40 | ret:push(i) |
|---|
| 41 | end) |
|---|
| 42 | return ret |
|---|
| 43 | end, |
|---|
| 44 | |
|---|
| 45 | __sub = function (op1, op2) |
|---|
| 46 | local ret = List.new() |
|---|
| 47 | op1:each(function (i) |
|---|
| 48 | local exists = false |
|---|
| 49 | op2:each(function(j) |
|---|
| 50 | if i == j then exists = true end |
|---|
| 51 | end) |
|---|
| 52 | if not exists then ret:push(i) end |
|---|
| 53 | end) |
|---|
| 54 | return ret |
|---|
| 55 | end, |
|---|
| 56 | |
|---|
| 57 | __eq = function (op1, op2) |
|---|
| 58 | return op1:join() == op2:join() |
|---|
| 59 | end, |
|---|
| 60 | |
|---|
| 61 | initialize = function (self, ...) |
|---|
| 62 | self.n = 0 |
|---|
| 63 | for i, v in ipairs(arg) do self:push(v) end |
|---|
| 64 | end, |
|---|
| 65 | |
|---|
| 66 | unshift = function (self, value) |
|---|
| 67 | self.n = self.n + 1 |
|---|
| 68 | for i = self.n, 1, -1 do |
|---|
| 69 | self[i+1] = self[i] |
|---|
| 70 | end |
|---|
| 71 | self[1] = value |
|---|
| 72 | return self |
|---|
| 73 | end, |
|---|
| 74 | |
|---|
| 75 | push = function (self, value) |
|---|
| 76 | self.n = self.n + 1 |
|---|
| 77 | self[self.n] = value |
|---|
| 78 | return self |
|---|
| 79 | end, |
|---|
| 80 | |
|---|
| 81 | shift = function (self) |
|---|
| 82 | local ret = self[1] |
|---|
| 83 | for i = 2, self.n do |
|---|
| 84 | self[i-1] = self[i] |
|---|
| 85 | end |
|---|
| 86 | self[self.n] = nil |
|---|
| 87 | self.n = self.n - 1 |
|---|
| 88 | return ret |
|---|
| 89 | end, |
|---|
| 90 | |
|---|
| 91 | pop = function (self) |
|---|
| 92 | local ret = self[self.n] |
|---|
| 93 | self[self.n] = nil |
|---|
| 94 | self.n = self.n - 1 |
|---|
| 95 | return ret |
|---|
| 96 | end, |
|---|
| 97 | |
|---|
| 98 | clear = function (self) |
|---|
| 99 | for i, v in ipairs(self) do |
|---|
| 100 | self[i] = nil |
|---|
| 101 | end |
|---|
| 102 | self.n = 0 |
|---|
| 103 | end, |
|---|
| 104 | |
|---|
| 105 | size = function (self) |
|---|
| 106 | return self.n |
|---|
| 107 | end, |
|---|
| 108 | |
|---|
| 109 | first = function (self, n) |
|---|
| 110 | if n then |
|---|
| 111 | local ret = List.new() |
|---|
| 112 | for i = 1, n do |
|---|
| 113 | ret:push(self[i]) |
|---|
| 114 | end |
|---|
| 115 | return ret |
|---|
| 116 | else |
|---|
| 117 | return self[1] |
|---|
| 118 | end |
|---|
| 119 | end, |
|---|
| 120 | |
|---|
| 121 | last = function (self, n) |
|---|
| 122 | if n then |
|---|
| 123 | local ret = List.new() |
|---|
| 124 | for i = self.n - n + 1, self.n do |
|---|
| 125 | ret:push(self[i]) |
|---|
| 126 | end |
|---|
| 127 | return ret |
|---|
| 128 | else |
|---|
| 129 | return self[self.n] |
|---|
| 130 | end |
|---|
| 131 | end, |
|---|
| 132 | |
|---|
| 133 | join = function (self, sep) |
|---|
| 134 | if not sep then sep = ", " end |
|---|
| 135 | local ret = "" |
|---|
| 136 | if self:size() > 0 then |
|---|
| 137 | for i = 1, self.n - 1 do |
|---|
| 138 | ret = ret .. tostring(self[i]) .. sep |
|---|
| 139 | end |
|---|
| 140 | ret = ret .. tostring(self[self.n]) |
|---|
| 141 | end |
|---|
| 142 | return ret |
|---|
| 143 | end, |
|---|
| 144 | |
|---|
| 145 | each = function (self, fun) |
|---|
| 146 | for i = 1, self.n do |
|---|
| 147 | fun(self[i]) |
|---|
| 148 | end |
|---|
| 149 | end, |
|---|
| 150 | |
|---|
| 151 | eachWithIndex = function (self, fun) |
|---|
| 152 | for i = 1, self.n do |
|---|
| 153 | fun(self[i], i) |
|---|
| 154 | end |
|---|
| 155 | end, |
|---|
| 156 | |
|---|
| 157 | map = function (self, fun) |
|---|
| 158 | local ret = List.new() |
|---|
| 159 | self:each(function (i) |
|---|
| 160 | ret:push(fun(i)) |
|---|
| 161 | end) |
|---|
| 162 | return ret |
|---|
| 163 | end, |
|---|
| 164 | |
|---|
| 165 | select = function (self, fun) |
|---|
| 166 | local ret = List.new() |
|---|
| 167 | self:each(function (i) |
|---|
| 168 | if fun(i) then ret:push(i) end |
|---|
| 169 | end) |
|---|
| 170 | return ret |
|---|
| 171 | end, |
|---|
| 172 | |
|---|
| 173 | min = function (self, fun) |
|---|
| 174 | if not fun then fun = function (i) return i end end |
|---|
| 175 | local tmp, ret, t |
|---|
| 176 | self:each(function (i) |
|---|
| 177 | if not tmp then |
|---|
| 178 | tmp = fun(i) |
|---|
| 179 | ret = i |
|---|
| 180 | else |
|---|
| 181 | t = fun(i) |
|---|
| 182 | if t < tmp then |
|---|
| 183 | tmp = t |
|---|
| 184 | ret = i |
|---|
| 185 | end |
|---|
| 186 | end |
|---|
| 187 | end) |
|---|
| 188 | return ret |
|---|
| 189 | end, |
|---|
| 190 | |
|---|
| 191 | max = function (self, fun) |
|---|
| 192 | if not fun then fun = function (i) return i end end |
|---|
| 193 | local tmp, ret, t |
|---|
| 194 | self:each(function (i) |
|---|
| 195 | if not tmp then |
|---|
| 196 | tmp = fun(i) |
|---|
| 197 | ret = i |
|---|
| 198 | else |
|---|
| 199 | t = fun(i) |
|---|
| 200 | if t > tmp then |
|---|
| 201 | tmp = t |
|---|
| 202 | ret = i |
|---|
| 203 | end |
|---|
| 204 | end |
|---|
| 205 | end) |
|---|
| 206 | return ret |
|---|
| 207 | end, |
|---|
| 208 | |
|---|
| 209 | sort = function (self, fun) |
|---|
| 210 | if not fun then fun = function (a, b) return (a < b) end end |
|---|
| 211 | |
|---|
| 212 | -- based on http://nanto.asablo.jp/blog/2007/02/06/1167686 |
|---|
| 213 | local function qsort(data, start, finish, cont) |
|---|
| 214 | if start >= finish then return cont(data) end |
|---|
| 215 | |
|---|
| 216 | local pivotPos = start |
|---|
| 217 | local pivot = data[pivotPos] |
|---|
| 218 | |
|---|
| 219 | local i = start + 1 |
|---|
| 220 | while i < finish + 1 do |
|---|
| 221 | if fun(data[i], pivot) then |
|---|
| 222 | local temp = data[i] |
|---|
| 223 | data[i] = data[pivotPos + 1] |
|---|
| 224 | data[pivotPos + 1] = data[pivotPos] |
|---|
| 225 | data[pivotPos] = temp |
|---|
| 226 | pivotPos = pivotPos + 1 |
|---|
| 227 | end |
|---|
| 228 | i = i + 1 |
|---|
| 229 | end |
|---|
| 230 | |
|---|
| 231 | return qsort(data, start, pivotPos, function (partiallySortedData) |
|---|
| 232 | return qsort(partiallySortedData, pivotPos + 1, finish, function (entirelySortedData) |
|---|
| 233 | return cont(entirelySortedData); |
|---|
| 234 | end); |
|---|
| 235 | end) |
|---|
| 236 | end |
|---|
| 237 | |
|---|
| 238 | local ret = List.new(unpack(self)) |
|---|
| 239 | return qsort(ret, 1, ret.n, function (data) return data end) |
|---|
| 240 | end, |
|---|
| 241 | |
|---|
| 242 | sortBy = function (self, fun) |
|---|
| 243 | return self:map(function (i) |
|---|
| 244 | return { o = i, s = fun(i) } |
|---|
| 245 | end):sort(function (a, b) |
|---|
| 246 | return (a.s < b.s) |
|---|
| 247 | end):map(function (i) |
|---|
| 248 | return i.o |
|---|
| 249 | end) |
|---|
| 250 | end, |
|---|
| 251 | |
|---|
| 252 | isEmpty = function (self) |
|---|
| 253 | return self.n == 0 |
|---|
| 254 | end, |
|---|
| 255 | |
|---|
| 256 | isInclude = function (self, value) |
|---|
| 257 | local ret = false |
|---|
| 258 | self:each(function (i) |
|---|
| 259 | if i == value then ret = true end |
|---|
| 260 | end) |
|---|
| 261 | return ret |
|---|
| 262 | end, |
|---|
| 263 | |
|---|
| 264 | deleteAt = function(self, index) |
|---|
| 265 | if index < 0 or index > self.n then return nil end |
|---|
| 266 | local ret = self[index] |
|---|
| 267 | for i = index + 1, self.n do |
|---|
| 268 | self[i-1] = self[i] |
|---|
| 269 | end |
|---|
| 270 | self.n = self.n - 1 |
|---|
| 271 | return ret |
|---|
| 272 | end, |
|---|
| 273 | |
|---|
| 274 | delete = function (self, value) |
|---|
| 275 | local ret |
|---|
| 276 | for i = 1, self.n do |
|---|
| 277 | if self[i] == value then |
|---|
| 278 | ret = self:deleteAt(i) |
|---|
| 279 | end |
|---|
| 280 | end |
|---|
| 281 | return ret |
|---|
| 282 | end, |
|---|
| 283 | } |
|---|