Trong Lua, hai bảng được tạo riêng được coi là "khác". Nhưng nếu bạn tạo một bảng một lần, bạn có thể gán nó cho bất kỳ biến nào bạn muốn, và khi bạn so sánh chúng, Lua sẽ cho bạn biết rằng chúng là như nhau. Nói cách khác:
t = {}
key = { a = "a" }
t[key] = 4
key2 = key
...
t[key2] -- returns 4
Vì vậy, đó là cách đơn giản, sạch sẽ để làm những gì bạn muốn.Lưu trữ key
ở đâu đó, vì vậy bạn có thể truy xuất lại 4
bằng cách sử dụng nó. Điều này cũng rất nhanh.
Nếu bạn thực sự không muốn làm điều đó ... tốt, có một cách. Nhưng nó là loại không hiệu quả và xấu xí.
Phần đầu tiên là tạo một hàm so sánh hai bảng riêng biệt. Nó sẽ trả về true nếu hai bảng là "tương đương", và sai nếu chúng không. Hãy gọi nó là tương đương. Nó sẽ hoạt động như sau:
equivalent({a=1},{a=1}) -- true
equivalent({a=1,b=2}, {a=1}) -- false
equivalent({a={b=1}}, {a={b=2}}) -- false
Hàm này phải đệ quy, để xử lý các bảng có chứa bảng. Nó cũng không được đánh lừa nếu một trong các bảng "chứa" khác, nhưng có nhiều yếu tố. Tôi đi ra với việc thực hiện này; có lẽ có những cái tốt hơn ngoài kia.
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
Tôi sẽ không giải thích chức năng ở đây. Tôi hy vọng nó là rõ ràng đủ những gì nó làm.
Phần khác của câu đố bao gồm việc tạo t
sử dụng chức năng equivalent
khi so sánh các phím. Điều này có thể được thực hiện với thao tác có thể chỉnh sửa cẩn thận và một bảng "lưu trữ" bổ sung.
Chúng tôi về cơ bản biến đổi t
thành kẻ mạo danh. Khi mã của chúng ta bảo nó lưu trữ một giá trị dưới một khóa, nó không tự lưu nó; thay vào đó nó đưa nó vào bảng phụ (chúng tôi sẽ gọi là store
). Khi mã yêu cầu t
cho một giá trị, nó tìm kiếm nó trong store
, nhưng sử dụng hàm equivalent
để nhận được nó.
Đây là mã:
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
})
Cách sử dụng Ví dụ:
t[{a = 1}] = 4
print(t[{a = 1}]) -- 4
print(t[{a = 1, b = 2}]) -- nil
Cảm ơn đã phản ứng. Lý do tôi muốn điều này là cho một nhiệm vụ NLP. Tôi trích xuất các cụm từ mà tôi lưu trữ dưới dạng các bảng lua (mỗi mã thông báo trong cụm từ như một giá trị được ánh xạ tới một chỉ mục bằng cách sử dụng table.insert) và tôi muốn đếm tần suất của các cụm từ. Tôi biết rằng có nhiều cách khác để làm những gì tôi muốn (ví dụ: ghép nối cụm từ và sử dụng chuỗi nối đó làm khóa) nhưng nó sẽ yêu cầu các bước triển khai bổ sung và nó sẽ không hoàn toàn sạch sẽ. Tôi khá chắc chắn bạn có thể làm những gì tôi muốn trong Java và, là mới để lua, tôi đang cố gắng để xem nếu có một tương tự – akobre01
Như vậy một hàm băm là khó để viết bởi vì thứ tự mà bảng được đi qua phụ thuộc vào cách nó được tạo ra và do đó các bảng có cùng mục nhập có thể có các traversals khác nhau. – lhf
Đó là lý do tại sao tôi nói về việc thu thập các chìa khóa vào một bảng và phân loại nó để đảm bảo thứ tự chính xác nhất quán. –