Jak sprawdzić, czy tabela zawiera element w Lua?
Czy istnieje metoda sprawdzania, czy tabela zawiera wartość ? Mam swoją (naiwną) funkcję, ale zastanawiałem się, czy istnieje coś "oficjalnego" do tego? Albo coś bardziej wydajnego...
function table.contains(table, element)
for _, value in pairs(table) do
if value == element then
return true
end
end
return false
end
Przy okazji, głównym powodem, dla którego używam tej funkcji, jest używanie tabel jako zestawów, tj. bez duplikatów elementów. Czy jest coś jeszcze, czego mógłbym użyć ?
4 answers
Wartości można umieścić jako klucze tabeli. Na przykład:
function addToSet(set, key)
set[key] = true
end
function removeFromSet(set, key)
set[key] = nil
end
function setContains(set, key)
return set[key] ~= nil
end
Jest bardziej w pełni funkcjonalny przykład tutaj .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-11 02:07:41
Biorąc pod uwagę twoją reprezentację, twoja funkcja jest tak wydajna, jak to tylko możliwe. Oczywiście, jak zauważyli inni (i jak praktykowali w językach starszych niż Lua), rozwiązaniem Twojego prawdziwego problemu jest zmiana reprezentacji. Gdy masz tabele i chcesz mieć zestawy, zamieniasz tabele w zestawy, używając elementu set jako klucza i true
jako wartości. +1 do interjay.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-24 20:03:25
Nie mogę wymyślić innego sposobu porównywania wartości, ale jeśli użyjesz elementu zestawu jako klucza, możesz ustawić wartość na cokolwiek innego niż nil. Następnie otrzymujesz szybkie wyszukiwanie bez konieczności przeszukiwania całego stołu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-17 16:43:37
Wiem, że to stary post, ale chciałem dodać coś dla potomności. Prostym sposobem obsługi problemu, który masz, jest utworzenie innej tabeli, o wartości do klucza.
Ie. masz 2 tabele, które mają tę samą wartość, jeden wskazuje w jednym kierunku, jeden wskazuje w drugim.
function addValue(key, value)
if (value == nil) then
removeKey(key)
return
end
_primaryTable.key = value
_secodaryTable.value = key
end
function removeKey(key)
local value = _primaryTable.key
if (value == nil) then
return
end
_primaryTable.key = nil
_secondaryTable.value = nil
end
function getValue(key)
return _primaryTable.key
end
function containsValue(value)
return _secondaryTable.value ~= nil
end
Możesz następnie odpytywać nową tabelę, aby sprawdzić, czy ma klucz "element". Zapobiega to konieczności iteracji przez każdą wartość drugiej tabeli.
Jeśli okaże się, że nie możesz użyj 'element' jako klucza, ponieważ nie jest to na przykład ciąg znaków, a następnie dodaj na nim na przykład sumę kontrolną lub 'toString', a następnie użyj tego jako klucza.
Dlaczego chcesz to zrobić? Jeśli Twoje tabele są bardzo duże, czas na powtórzenie każdego elementu będzie znaczący, co uniemożliwi ci robienie tego bardzo często. Dodatkowy narzut pamięci będzie stosunkowo mały, ponieważ będzie przechowywał 2 wskaźniki do tego samego obiektu, a nie 2 kopie tego samego obiektu. Jeśli tabele są bardzo małe, wtedy będzie to miało znacznie mniejsze znaczenie, w rzeczywistości może być nawet szybciej iterację niż mieć inne wyszukiwanie map.Sformułowanie pytania sugeruje jednak, że masz wiele spraw do załatwienia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-02 09:15:40