diff options
author | stevedonovan <steve.j.donovan@gmail.com> | 2011-02-19 17:34:12 +0300 |
---|---|---|
committer | stevedonovan <steve.j.donovan@gmail.com> | 2011-02-19 17:34:12 +0300 |
commit | cecfaee1fe72297df690ef3c4c58e60c18255ff6 (patch) | |
tree | 2f5790afbef24c555661eda74f181e46c83cad54 /lua/pl/Map.lua | |
parent | 440c6310fbcca664dc1564e50e0ef9ef3bfc93db (diff) |
classes now sit in their own modules
Diffstat (limited to 'lua/pl/Map.lua')
-rw-r--r-- | lua/pl/Map.lua | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/lua/pl/Map.lua b/lua/pl/Map.lua new file mode 100644 index 0000000..9feeb2c --- /dev/null +++ b/lua/pl/Map.lua @@ -0,0 +1,104 @@ +---utils keeps the predefined metatables for these useful interfaces, +-- so that other modules (such as tablex) can tag their output accordingly. +-- However, users are not required to use this module. +local tablex = require 'pl.tablex' +local utils = require 'pl.utils' +local stdmt = utils.stdmt +local is_callable = utils.is_callable +local tmakeset,deepcompare,merge,keys,difference,tupdate = tablex.makeset,tablex.deepcompare,tablex.merge,tablex.keys,tablex.difference,tablex.update + +local pretty_write = require 'pl.pretty' . write +local Map = stdmt.Map +local Set = stdmt.Set +local List = stdmt.List + +local class = require 'pl.class' + +-- the Map class --------------------- +class(nil,nil,Map) + +local function makemap (m) + return setmetatable(m,Map) +end + +function Map:_init (t) + local mt = getmetatable(t) + if mt == Set or mt == Map then + self:update(t) + else + return t -- otherwise assumed to be a map-like table + end +end + + +local function makelist(t) + return setmetatable(t,List) +end + +--- list of keys. +Map.keys = tablex.keys + +--- list of values. +Map.values = tablex.values + +--- return an iterator over all key-value pairs. +function Map:iter () + return pairs(self) +end + +--- return a List of all key-value pairs, sorted by the keys. +function Map:items() + local ls = makelist(tablex.pairmap (function (k,v) return makelist {k,v} end, self)) + ls:sort(function(t1,t2) return t1[1] < t2[1] end) + return ls +end + +-- Will return the existing value, or if it doesn't exist it will set +-- a default value and return it. +function Map:setdefault(key, defaultval) + return self[key] or self:set(key,defaultval) or defaultval +end + +--- size of map. +-- note: this is a relatively expensive operation! +-- @class function +-- @name Map:len +Map.len = tablex.size + +--- put a value into the map. +-- @param key the key +-- @param val the value +function Map:set (key,val) + self[key] = val +end + +--- get a value from the map. +-- @param key the key +-- @return the value, or nil if not found. +function Map:get (key) + return rawget(self,key) +end + +local index_by = tablex.index_by + +-- get a list of values indexed by a list of keys. +-- @param keys a list-like table of keys +-- @return a new list +function Map:getvalues (keys) + return makelist(index_by(self,keys)) +end + +Map.iter = pairs + +Map.update = tablex.update + +function Map:__eq (m) + -- note we explicitly ask deepcompare _not_ to use __eq! + return deepcompare(self,m,true) +end + +function Map:__tostring () + return pretty_write(self,'') +end + +return Map |