w Lua, dwa stoły tworzone osobno są uważane za „inny”. Ale jeśli utworzysz tabelę raz, możesz przypisać ją do dowolnych zmiennych, a kiedy porównasz je, Lua powie Ci, że są one równe. Innymi słowy:
t = {}
key = { a = "a" }
t[key] = 4
key2 = key
...
t[key2] -- returns 4
Tak, to jest proste, czyste sposób robienia tego, co chcesz.Przechowuj gdzieś numer key
, aby odzyskać numer 4
, korzystając z niego. Jest to również bardzo szybkie.
Jeśli naprawdę nie chce zrobić ... dobrze, jest na to sposób. Ale jest to rodzaj nieefektywnego i brzydkiego.
Pierwsza część polega na wykonaniu funkcji porównującej dwie oddzielne tabele. Zwraca wartość true, jeśli dwie tabele są "równoważne", a fałsz, jeśli nie są. Nazwijmy to równoważnym. Powinno to działać tak:
equivalent({a=1},{a=1}) -- true
equivalent({a=1,b=2}, {a=1}) -- false
equivalent({a={b=1}}, {a={b=2}}) -- false
Funkcja musi być rekurencyjne, do obsługi tabel, które zawierają tabele siebie. Nie należy też oszukiwać, jeśli jedna z tabel "zawiera" drugą, ale ma więcej elementów. Wyszedłem z tą implementacją; prawdopodobnie są tam lepsze.
local function equivalent(a,b)
if type(a) ~= 'table' then return a == b end
local counta, countb = 0, 0
for k,va in pairs(a) do
if not equivalent(va, b[k]) then return false end
counta = counta + 1
end
for _,_ in pairs(b) do countb = countb + 1 end
return counta == countb
end
Nie zamierzam tu wyjaśniać tej funkcji. Mam nadzieję, że jest wystarczająco jasne, co robi.
Druga część układanki polega na wykonaniu funkcji t
przy użyciu funkcji equivalent
podczas porównywania klawiszy. Można to zrobić poprzez ostrożną manipulację i dodatkową tabelę "przechowywania".
W zasadzie przekształcamy t
w oszusta. Kiedy nasz kod nakazuje mu zapisanie wartości pod kluczem, nie zapisuje go w sobie; zamiast tego podaje ją do dodatkowego stołu (będziemy to nazywać store
). Gdy kod prosi o podanie wartości t
, wyszukuje ją w store
, ale używa funkcji equivalent
, aby ją uzyskać.
Jest to kod: przykład
local function equivalent(a,b)
... -- same code as before
end
local store = {} -- this is the table that stores the values
t = setmetatable({}, {
__newindex = store,
__index = function(tbl, key)
for k,v in pairs(store) do
if equivalent(k,key) then return v end
end
end
})
Zastosowanie:
t[{a = 1}] = 4
print(t[{a = 1}]) -- 4
print(t[{a = 1, b = 2}]) -- nil
Dzięki za odpowiedzi. Powodem, dla którego tego chciałem, było zadanie NLP. Wyodrębniam zwroty, które przechowuję jako tabele lua (każdy token w wyrażeniu, jako wartość odwzorowaną na indeks przy użyciu table.insert) i chcę zliczyć częstotliwość fraz. Wiem, że są inne sposoby robienia tego, co chcę (np. Łączenie frazy i używanie tego połączonego ciągu jako klucza), ale wymagałoby to dodatkowych kroków implementacyjnych i nie byłoby tak czyste. Jestem całkiem pewny, że możesz robić to, co chcę w Javie i, będąc nowym użytkownikiem Lua, próbuję sprawdzić, czy jest analogowy – akobre01
Taka funkcja skrótu jest trudna do napisania, ponieważ kolejność, w której są wykonywane tabele, zależy od tego, jak został utworzony i dlatego tabele z tymi samymi wpisami mogą mieć różne przechodnie. – lhf
Dlatego właśnie powiedziałem o zebraniu kluczy do stołu i posortowaniu go, aby zapewnić spójną kolejność klawiszy. –