数组列表 list
# 在table的基础山增加了更直观的列表操作函数,同时使用了_count来跟踪元素数量
local list = {} list.__cname = "util.list" local null = {} list.null = null list.__newindex = function(self, k, v) if "number" == type(k) then error(string.format("use list:Add to add new index: %s", k)) end rawset(self, k, v) end list.__index = list local function Swap(tb, index1, index2) local temp = tb[index1] tb[index1] = tb[index2] tb[index2] = temp end function list.new() local obj = {} setmetatable(obj, list) obj:ctor() return obj end function list.attach(arrTb) setmetatable(arrTb, list) arrTb._count = #arrTb arrTb._ver = 0 end function list:ctor() self._count = 0 self._ver = 0 end function list:_IcrVersion() self._ver = self._ver + 1 end function list:Clear() if 0 == self._count then return end for i=1,self._count do self[i] = nil end self._count = 0 self:_IcrVersion() end function list:GetCount() return self._count end function list:Add(v) if nil == v then v = null end self._count = self._count + 1 rawset(self, self._count, v) --self[self._count] = v self:_IcrVersion() end function list:Set(index, v) if nil == v then v = null end if index > self._count then return end self[index] = v self:_IcrVersion() end function list:InsertAt(index, v) local count_1 = self._count + 1 if index < 1 or index > count_1 then return end if nil == v then v = null end if index == count_1 then self._count = self._count + 1 rawset(self, self._count, v) else for i=self._count,index,-1 do --往后移动 self[i+1] = self[i] end rawset(self, index, v) self._count = self._count + 1 end self:_IcrVersion() end function list:GetAt(index) --if index < 1 or index > self._count then return nil end return self[index] end function list:RemoveAt(index) if index < 1 or index > self._count then return false end local oldValue = self[index] if index == self._count then self[index] = nil else for i=index,self._count-1 do --往前移动 self[i] = self[i+1] end self[self._count] = nil end self._count = self._count - 1 self:_IcrVersion() return true, oldValue end function list:RemoveRange(index, count) if index < 1 or index > self._count then return false end local index2 = index + count if index2 > self._count then --删除尾部n个元素 for i=index,self._count do self[i] = nil end self._count = index - 1 else local i = index for j=index2,self._count do --往前移动 self[i] = self[j] i = i + 1 end for j=i,self._count do --移掉的置为nil self[j] = nil end self._count = self._count - count end self:_IcrVersion() return true end function list:Remove(v) local index = self:IndexOf(v) if index > 0 then self:RemoveAt(index) return true end return false end function list:Contains(v) return self:IndexOf(v) > 0 end function list:IndexOf(v) if self._count < 1 then return -1 end for i=1,self._count do if self[i] == v then return i end end return -1 end function list:Find(matchFunc) if self._count < 1 then return -1, nil end for i=1,self._count do local item = self[i] if matchFunc(i, item) then return i, item end end return -1, nil end function list:LastIndexOf(v) if self._count < 1 then return -1 end for i=self._count,1,-1 do if self[i] == v then return i end end return -1 end function list:FindLast(matchFunc) if self._count < 1 then return -1, nil end for i=self._count,1,-1 do local item = self[i] if matchFunc(i, item) then return i, item end end return -1, nil end function list:Sort(func) if self._count < 1 then return end table.sort(self.arr, func) self:_IcrVersion() end function list:Reverse() if self._count < 2 then return end local i = 1 local j = self._count while i < j do Swap(self, i, j) i = i + 1 j = j - 1 end self:_IcrVersion() end function list:Shuffle() local count = self._count if 1 == count then return end local arr = self for i=1,count do local r = math.random(count) local temp = arr[i] arr[i] = arr[r] arr[r] = temp end self:_IcrVersion() end function list:__tostring() if 0 == self._count then return "" end local strTb = {} for i=1,self._count do table.insert(strTb, tostring(self[i])) end return table.concat(strTb, ",") end function list:pairs() error("use list:ipairs") end function list:ipairs() local iteratorCur = 1 local version = self._ver local function iterator(tb, key) if version ~= self._ver then error("list modified in Iterator") end if iteratorCur > self._count then return nil end local k = iteratorCur iteratorCur = iteratorCur + 1 return k, self[k] end return iterator end function list:IsReadOnly() return false end return list