表格工具

lua-users home
wiki

將表格轉換為字串

產生一個簡潔、一目瞭然的表格表示。採用相互遞迴。

function table.val_to_str ( v )
  if "string" == type( v ) then
    v = string.gsub( v, "\n", "\\n" )
    if string.match( string.gsub(v,"[^'\"]",""), '^"+$' ) then
      return "'" .. v .. "'"
    end
    return '"' .. string.gsub(v,'"', '\\"' ) .. '"'
  else
    return "table" == type( v ) and table.tostring( v ) or
      tostring( v )
  end
end

function table.key_to_str ( k )
  if "string" == type( k ) and string.match( k, "^[_%a][_%a%d]*$" ) then
    return k
  else
    return "[" .. table.val_to_str( k ) .. "]"
  end
end

function table.tostring( tbl )
  local result, done = {}, {}
  for k, v in ipairs( tbl ) do
    table.insert( result, table.val_to_str( v ) )
    done[ k ] = true
  end
  for k, v in pairs( tbl ) do
    if not done[ k ] then
      table.insert( result,
        table.key_to_str( k ) .. "=" .. table.val_to_str( v ) )
    end
  end
  return "{" .. table.concat( result, "," ) .. "}"
end

範例

t = {['foo']='bar',11,22,33,{'a','b'}}
print( table.tostring( t ) )
這會印出 {11,22,33,{"a","b"},foo="bar"}

遞迴表格列印/字串化/序列化 =

TableSerialization

計算表格中項目的發生次數

-- Count the number of times a value occurs in a table 
function table_count(tt, item)
  local count
  count = 0
  for ii,xx in pairs(tt) do
    if item == xx then count = count + 1 end
  end
  return count
end

從表格中移除複製品

-- Remove duplicates from a table array (doesn't currently work
-- on key-value tables)
function table_unique(tt)
  local newtable
  newtable = {}
  for ii,xx in ipairs(tt) do
    if(table_count(newtable, xx) == 0) then
      newtable[#newtable+1] = xx
    end
  end
  return newtable
end

從清單中隨機抽樣

RandomSample 有更好的演算法,但它在 math.random 中遇到相同的問題

-- Careful of random number seeding here- you will need to randomly
-- seed before calling this
function randomlist(l, samp)
  local newlist
  newlist = {}
  if not samp then 
    samp = 0 
  else
    samp = #l - samp
  end
  while #l > samp do
    local idx
    idx = math.random(1, #l)
    newlist[#newlist + 1] = l[idx]
    table.remove(l, idx)
  end
  return newlist
end

將表格使用分隔符轉換為字串

問題:使用者應該使用內建函式 table.concat(table,divider)

-- implode(separator, table)
function implode(d,p)
  local newstr
  newstr = ""
  if(#p == 1) then
    return p[1]
  end
  for ii = 1, (#p-1) do
    newstr = newstr .. p[ii] .. d
  end
  newstr = newstr .. p[#p]
  return newstr
end

從清單產生組合

-- combo({a,b,c},2) ==> a,b a,c b,c
-- an iterating solution would be appreciated too
function combo(lst, n)
  local a, number, select, newlist
  newlist = {}
  number = #lst
  select = n
  a = {}
  for i=1,select do
    a[#a+1] = i
  end
  newthing = {}
  while(1) do
    local newrow = {}
    for i = 1,select do
      newrow[#newrow + 1] = lst[a[i]]
    end
    newlist[#newlist + 1] = newrow
    i=select
    while(a[i] == (number - select + i)) do
      i = i - 1
    end
    if(i < 1) then break end
    a[i] = a[i] + 1
    for j=i, select do
      a[j] = a[i] + j - i
    end
  end
  return newlist
end

從清單產生組合 - 迭代版本

對大型 t 和 n 會較快,因為它只更新從組合到組合中變更的項目,而不是在每次迭代時重新建立組合列。

RichardWarburton 提供。

function combo(t,n)
  local n,max,tn,output=n,#t,{},{}
  for x=1,n do tn[x],output[x]=x,t[x] end -- Generate 1st combo
  tn[n]=tn[n]-1 -- Needed to output 1st combo
  return function() -- Iterator fn
    local t,tn,output,x,n,max=t,tn,output,n,n,max
    while tn[x]==max+x-n do x=x-1 end -- Locate update point
    if x==0 then return nil end -- Return if no update point
    tn[x]=tn[x]+1 -- Add 1 to update point (UP)
    output[x]=t[tn[x]] -- Update output at UP
    for i=x+1,n do 
      tn[i]=tn[i-1]+1 -- Update points to right of UP
      output[i]=t[tn[i]] -- Update output to refect change in points
    end
    return output
  end
end

將一個表格中的值插入另一個表格

--DavidManura

-- tinsertvalues(t, [pos,] values)
-- similar to table.insert but inserts values from given table "values",
-- not the object itself, into table "t" at position "pos".
-- note: an optional extension is to allow selection of a slice of values:
--   tinsertvalues(t, [pos, [vpos1, [vpos2, ]]] values)
-- DavidManura, public domain, https://lua-users.dev.org.tw/wiki/TableUtils
function tinsertvalues(t, ...)
  local pos, values
  if select('#', ...) == 1 then
    pos,values = #t+1, ...
  else
    pos,values = ...
  end
  if #values > 0 then
    for i=#t,pos,-1 do
      t[i+#values] = t[i]
    end
    local offset = 1 - pos
    for i=pos,pos+#values-1 do
      t[i] = values[i + offset]
    end
  end
end
--[[ tests:
  local t = {5,6,7}
  tinsertvalues(t, {8,9})
  tinsertvalues(t, {})
  tinsertvalues(t, 1, {1,4})
  tinsertvalues(t, 2, {2,3})
  assert(table.concat(t, '') == '123456789')
--]]

迭代在表格中非 ipair 鍵

LuaList:2010-12/msg01143.html («hpairs» 討論)。

另請見

評論

也許將其重新命名為 TableRecipes? (像是 StringRecipes)。


近期變更 · 偏好設定
編輯 · 歷史記錄
最後編輯時間 2011 年 1 月 2 日 下午 2:31 格林威治標準時間 (diff)