Сравнение двух таблиц индекса по значению индекса в lua - PullRequest
5 голосов
/ 04 января 2012

Я пытаюсь сравнить две таблицы одинаковой длины с функцией, так как я не знаю другого способа сделать это.Тем не менее, с помощью следующей функции она не может зарегистрироваться, и я понятия не имею, почему.Я надеюсь, что кто-то может дать представление об этой проблеме или может лучше сравнить две таблицы.

Таблицы заполняются следующим кодом:

str = "parameters determined by program (all digits)"
tableone = {}
for word in str:gmatch("%d") do table.insert(tableone,word) end

Это идентично дляобе таблицы, кроме, конечно, имен отдельных таблиц.Таблицы заполняются правильно и отображаются правильно, когда я их печатаю.Вот две таблицы ради этого вопроса:

tableone = {}
tabletwo = {}
for i=1,4 do table.insert(tableone, i) end
for i=1,4 do table.insert(tabletwo, i) end

Очевидно, что эти две таблицы будут равны друг другу.Функция, которую я написал для сравнения таблиц индексов, выглядит следующим образом:

function comparetables(t1, t2)
matchct = 0
 for i=1,#t1 do
    if t1[i] == t2[i] then
    matchct = matchct + 1
    end
if matchct == #t1 then
return true
end
end

Я попытался выполнить

print(comparetables(tableone,tabletwo))

, чтобы посмотреть, будет ли напечатано «true», но не повезло.Мне кажется, это должно работать без проблем.Но это не так.Что мне не хватает?Я пытался найти что-то вроде функции table.compare, которую кто-то, возможно, уже написал, но мне не повезло найти такую.Спасибо за любые предложения!

Дополнительная информация:

Причина, по которой я сравниваю таблицы, заключается в игре типа mastermaind.Это означает, что следующие три правила должны применяться при сравнении таблиц.Функция, которую я создал, состояла в том, чтобы просто начать меня, думая, что я мог бы работать оттуда.

  1. При сравнении таблиц, если числа совпадают, Ccount увеличивается на 1.
  2. При сравнениитаблиц, если значение существует в другой позиции индекса, увеличьте Pcount на 1

Например, с таблицей значений {1, 3, 3, 4} и предположением {4, 4, 3, 1}, он вернет Pcount 2 (один 4 и 1) и Ccount 1 (три в третьей позиции).Я думаю, что одной из самых сложных частей будет сравнение, чтобы понять, что вторые 4 в предположении не должны увеличивать Pcount вообще.

Ответы [ 2 ]

5 голосов
/ 04 января 2012

Небольшой вариант в вашем коде, который должен работать:

function comparetables(t1, t2)
  if #t1 ~= #t2 then return false end
  for i=1,#t1 do
    if t1[i] ~= t2[i] then return false end
  end
  return true
end

Однако я использую нечто более похожее на это: он проверяет типы аргументов, их метатаблицы и несколько других случаев.

-- This is not clever enough to find matching table keys
-- i.e. this will return false
--   recursive_compare( { [{}]:1 }, { [{}]:1 } )
-- but this is unusual enough for me not to care ;)
-- It can also get stuck in infinite loops if you use it on 
-- an evil table like this:
--     t = {}
--     t[1] = t

function recursive_compare(t1,t2)
  -- Use usual comparison first.
  if t1==t2 then return true end
  -- We only support non-default behavior for tables
  if (type(t1)~="table") then return false end
  -- They better have the same metatables
  local mt1 = getmetatable(t1)
  local mt2 = getmetatable(t2)
  if( not recursive_compare(mt1,mt2) ) then return false end

  -- Check each key-value pair
  -- We have to do this both ways in case we miss some.
  -- TODO: Could probably be smarter and not check those we've 
  -- already checked though!
  for k1,v1 in pairs(t1) do
    local v2 = t2[k1]
    if( not recursive_compare(v1,v2) ) then return false end
  end
  for k2,v2 in pairs(t2) do
    local v1 = t1[k2]
    if( not recursive_compare(v1,v2) ) then return false end
  end

  return true  
end

Вот пример его использования:

print( recursive_compare( {1,2,3,{1,2,1}}, {1,2,3,{1,2,1}} ) ) -- prints true
print( recursive_compare( {1,2,3,{1,2,1}}, {2,2,3,{1,2,3}} ) ) -- prints false
3 голосов
/ 04 января 2012

Если вы сравниваете объекты, которые являются более объектными, чем табличные в объектно-ориентированном смысле, то я бы посмотрел на реализацию функций способом lua OO.

Нечто подобное должно сработать:

GameState = {}
GameState.mt = {}
GameState.mt.fns = {}
GameState.mt.__index =  GameState.mt.fns

function GameState.new(a,b,c,d)
-- TODO: put argument checks here...
  local retval = {}
  retval[1] = a
  retval[2] = b
  retval[3] = c
  retval[4] = d
  setmetatable(retval, GameState.mt)
  return retval
end

function GameState.mt.fns.print( self )
  print(" GameState: ", self[1], self[2], self[3], self[4] )
end

function GameState.mt.__tostring( self )
  return "GameState: "..self[1].." "..self[2].." "..self[3].." "..self[4]
end

function GameState.mt.__eq(self, other)
  -- Check it's actually a GameState, and all its bits match
  return getmetatable(other)==GameState.mt and
    (self[1] == other[1]) and 
    (self[2] == other[2]) and 
    (self[3] == other[3]) and 
    (self[4] == other[4])
end

Тогда вы бы использовали это так:

state1 = GameState.new(1,2,3,4)
state2 = GameState.new(1,2,3,4)

print("State 1 is:")
state1:print()

print("State 2 is:")
print(state2)

print( "state1 == state2 : ", state1 == state2 )

print( "Changing state 2") 
state2[1]=2

print( "state1 == state2 : ", state1 == state2 )
...