Software / code / prosody
Comparison
util/set.lua @ 1028:594a07e753a0
util.set: Add metatable to sets to allow +, -, /, ==, tostring and to double as iterators
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Wed, 22 Apr 2009 18:00:45 +0100 |
| parent | 917:f12f88b3d4a1 |
| child | 1029:4ead03974759 |
comparison
equal
deleted
inserted
replaced
| 1027:fe2e3d3dba6a | 1028:594a07e753a0 |
|---|---|
| 1 local ipairs, pairs = | 1 local ipairs, pairs, setmetatable, next, tostring = |
| 2 ipairs, pairs; | 2 ipairs, pairs, setmetatable, next, tostring; |
| 3 local t_concat = table.concat; | |
| 3 | 4 |
| 4 module "set" | 5 module "set" |
| 5 | 6 |
| 7 local set_mt = {}; | |
| 8 function set_mt.__call(set, _, k) | |
| 9 return next(set._items, k); | |
| 10 end | |
| 11 function set_mt.__add(set1, set2) | |
| 12 return _M.union(set1, set2); | |
| 13 end | |
| 14 function set_mt.__sub(set1, set2) | |
| 15 return _M.difference(set1, set2); | |
| 16 end | |
| 17 function set_mt.__div(set, func) | |
| 18 local new_set, new_items = _M.new(); | |
| 19 local items, new_items = set._items, new_set._items; | |
| 20 for item in pairs(items) do | |
| 21 if func(item) then | |
| 22 new_items[item] = true; | |
| 23 end | |
| 24 end | |
| 25 return new_set; | |
| 26 end | |
| 27 function set_mt.__eq(set1, set2) | |
| 28 local set1, set2 = set1._items, set2._items; | |
| 29 for item in pairs(set1) do | |
| 30 if not set2[item] then | |
| 31 return false; | |
| 32 end | |
| 33 end | |
| 34 | |
| 35 for item in pairs(set2) do | |
| 36 if not set1[item] then | |
| 37 return false; | |
| 38 end | |
| 39 end | |
| 40 | |
| 41 return true; | |
| 42 end | |
| 43 function set_mt.__tostring(set) | |
| 44 local s, items = { }, set._items; | |
| 45 for item in pairs(items) do | |
| 46 s[#s+1] = tostring(item); | |
| 47 end | |
| 48 return t_concat(s, ", "); | |
| 49 end | |
| 50 | |
| 51 local items_mt = {}; | |
| 52 function items_mt.__call(items, _, k) | |
| 53 return next(items, k); | |
| 54 end | |
| 55 | |
| 6 function new(list) | 56 function new(list) |
| 7 local items = {}; | 57 local items = setmetatable({}, items_mt); |
| 8 local set = { _items = items }; | 58 local set = { _items = items }; |
| 9 | 59 |
| 10 function set:add(item) | 60 function set:add(item) |
| 11 items[item] = true; | 61 items[item] = true; |
| 12 end | 62 end |
| 43 | 93 |
| 44 if list then | 94 if list then |
| 45 set:add_list(list); | 95 set:add_list(list); |
| 46 end | 96 end |
| 47 | 97 |
| 48 return set; | 98 return setmetatable(set, set_mt); |
| 49 end | 99 end |
| 50 | 100 |
| 51 function union(set1, set2) | 101 function union(set1, set2) |
| 52 local set = new(); | 102 local set = new(); |
| 53 local items = set._items; | 103 local items = set._items; |