Brzmi jak pytanie „pozwól mi to wygooglować”, ale jakoś nie mogę znaleźć odpowiedzi. #
Operator Lua liczy tylko wpisy z kluczami całkowitymi, podobnie jak table.getn
:
tbl = {}
tbl["test"] = 47
tbl[1] = 48
print(#tbl, table.getn(tbl)) -- prints "1 1"
count = 0
for _ in pairs(tbl) do count = count + 1 end
print(count) -- prints "2"
Jak uzyskać liczbę wszystkich zgłoszeń bez ich liczenia?
dictionary[value] = #dictionary + 1
, gdzie#
reprezentuje liczbę wszystkich obiektów. Co ja zastanawiam się, dlaczego ty nie chcesz tego: w każdym sane przypadków użycia dla # (patrz odpowiedź do kaizer.se), liczba wszystkich obiektów jest dokładnie równa co już # zwrotów; wygląda na to, że # policzyć wszystko jest wyłącznie poprawą. Oczywiście jestem nowicjuszem w Lua i mogę nie mieć sensu.#
operator jest po prostu źle zdefiniowany. Jest to tak łatwe do naprawienia: po pierwsze, stwórz#
deterministyczne, a po drugie , wprowadź nowy operator lub funkcję, aby uzyskać liczbę cętek. Koniec historii ... Dlaczego oni muszą być tacy uparci? :)Odpowiedzi:
Masz już rozwiązanie w pytaniu - jedynym sposobem jest powtórzenie całej tabeli za pomocą
pairs(..)
.function tablelength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end
Zauważ też, że definicja operatora „#” jest nieco bardziej skomplikowana. Zilustruję to na podstawie poniższej tabeli:
t = {1,2,3} t[5] = 1 t[9] = 1
Zgodnie z instrukcją, każdy z 3, 5 i 9 to ważne wyniki dla
#t
. Jedynym rozsądnym sposobem użycia jest tablice jednej ciągłej części bez wartości zerowych.źródło
#
nie jest deterministyczna.According to the manual, any of 3, 5 and 9 are valid results for #t
. Zgodnie z instrukcją wywoływanie # na niesekwencjach jest niezdefiniowane . Oznacza to, że każdy wynik (-1, 3, 3,14, 5, 9) jest prawidłowy.Możesz skonfigurować metatabelę, aby śledzić liczbę wpisów, może to być szybsze niż iteracja, jeśli te informacje są często potrzebne.
źródło
Jest jeden sposób, ale może być rozczarowujący: użyj dodatkowej zmiennej (lub jednego z pól tabeli) do przechowywania liczby i zwiększaj ją za każdym razem, gdy dokonujesz wstawienia.
count = 0 tbl = {} tbl["test"] = 47 count = count + 1 tbl[1] = 48 count = count + 1 print(count) -- prints "2"
Nie ma innego sposobu, operator # będzie działał tylko na tablicach przypominających tablice z kolejnymi kluczami.
źródło
Najprostszym sposobem, jaki znam, aby uzyskać liczbę wpisów w tabeli, jest użycie znaku „#”. #tableName pobiera liczbę wpisów, o ile są one ponumerowane:
tbl={ [1] [2] [3] [4] [5] } print(#tbl)--prints the highest number in the table: 5
Niestety, jeśli nie są ponumerowane, to nie zadziała.
źródło
Możesz użyć biblioteki Penlight . Ma funkcję,
size
która podaje rzeczywisty rozmiar stołu.Zaimplementował wiele funkcji, których możemy potrzebować podczas programowania i których brakuje w Lua.
Oto przykład użycia go.
> tablex = require "pl.tablex" > a = {} > a[2] = 2 > a[3] = 3 > a['blah'] = 24 > #a 0 > tablex.size(a) 3
źródło
local function CountedTable(x) assert(type(x) == 'table', 'bad parameter #1: must be table') local new_t = {} local mt = {} -- `all` will represent the number of both local all = 0 for k, v in pairs(x) do all = all + 1 end mt.__newindex = function(t, k, v) if v == nil then if rawget(x, k) ~= nil then all = all - 1 end else if rawget(x, k) == nil then all = all + 1 end end rawset(x, k, v) end mt.__index = function(t, k) if k == 'totalCount' then return all else return rawget(x, k) end end return setmetatable(new_t, mt) end local bar = CountedTable { x = 23, y = 43, z = 334, [true] = true } assert(bar.totalCount == 4) assert(bar.x == 23) bar.x = nil assert(bar.totalCount == 3) bar.x = nil assert(bar.totalCount == 3) bar.x = 24 bar.x = 25 assert(bar.x == 25) assert(bar.totalCount == 4)
źródło
__newindex
wywołanie tylko wtedy, gdy zdefiniowany jest nowy klucz, więc nie ma szans na wywołanie,__newindex
gdy ustawimynil
istniejący klucz.wydaje się, że kiedy elementy tabeli zostaną dodane metodą insert, to getn zwróci poprawnie. W przeciwnym razie musimy policzyć wszystkie elementy
mytable = {} element1 = {version = 1.1} element2 = {version = 1.2} table.insert(mytable, element1) table.insert(mytable, element2) print(table.getn(mytable))
Wydrukuje 2 poprawnie
źródło
Natknąłem się na ten wątek i chcę opublikować inną opcję. Używam Luada wygenerowanego z kontrolera bloków, ale zasadniczo działa poprzez sprawdzanie wartości w tabeli, a następnie zwiększanie wartości sprawdzanej o 1. W końcu tabela się wyczerpie, a wartość w tym indeksie wyniesie zero.
Więc odejmij 1 od indeksu, który zwrócił zero, i to jest rozmiar tabeli.
Mam zmienną globalną dla TableSize, która jest ustawiona na wynik tej liczby.
function Check_Table_Size() local Count = 1 local CurrentVal = (CueNames[tonumber(Count)]) local repeating = true print(Count) while repeating == true do if CurrentVal ~= nil then Count = Count + 1 CurrentVal = CueNames[tonumber(Count)] else repeating = false TableSize = Count - 1 end end print(TableSize) end
źródło