2010-02-17 41 views
74

Có phương pháp nào để kiểm tra xem bảng có chứa giá trị không? Tôi có chức năng (ngây thơ) của riêng mình, nhưng tôi đã tự hỏi liệu có cái gì đó "chính thức" tồn tại cho điều đó? Hoặc một cái gì đó hiệu quả hơn ...Làm cách nào để kiểm tra xem bảng có chứa phần tử trong Lua không?

function table.contains(table, element) 
    for _, value in pairs(table) do 
    if value == element then 
     return true 
    end 
    end 
    return false 
end 

Bằng cách này, lý do chính tôi sử dụng chức năng này là sử dụng bảng làm bộ, nghĩa là không có phần tử trùng lặp. Có cái gì khác tôi có thể sử dụng?

+2

ký hiệu _ có nghĩa là gì? – Martin

+18

Đơn giản chỉ là biến "rác" có tên '_'. 'pairs()' trả về 'khóa, giá trị', nhưng trong ví dụ này, tôi chỉ cần giá trị. Nó là một loại quy ước (được thông qua trong cuốn sách "Lập trình trong Lua" http://www.lua.org/pil/index.html) để sử dụng biến '_' này để lưu trữ những thứ mà bạn không cần. – Wookai

Trả lời

91

Bạn có thể đặt các giá trị làm khóa của bảng. Ví dụ:

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 

Có một ví dụ đầy đủ hơn here.

+12

Một người dùng ẩn danh đề xuất sửa lỗi sau cho mã của bạn: Nếu giá trị trong tập hợp với khóa được chỉ định là FALSE thì hàm setContains() trả về giá trị sai mặc dù có một mục trong bảng có khóa được chỉ định. dòng "return set [key] ~ = nil" sửa lỗi đó. – oers

2

Tôi không thể nghĩ ra một cách khác để so sánh các giá trị, nhưng nếu bạn sử dụng phần tử của tập làm khóa, bạn có thể đặt giá trị thành bất kỳ giá trị nào khác không phải là 0. Sau đó, bạn nhận được tra cứu nhanh mà không phải tìm kiếm toàn bộ bảng.

22

Với đại diện của bạn, chức năng của bạn hiệu quả nhất có thể được thực hiện. Tất nhiên, như được ghi nhận bởi những người khác (và như được thực hành bằng các ngôn ngữ cũ hơn Lua), giải pháp cho vấn đề thực sự của bạn là thay đổi biểu diễn. Khi bạn có bảng và bạn muốn đặt, bạn chuyển bảng thành bộ bằng cách sử dụng phần tử đã đặt làm khóa và true làm giá trị. +1 để interjay.

0

Tôi biết đây là một bài đăng cũ, nhưng tôi muốn thêm một cái gì đó cho hậu thế. Cách đơn giản để xử lý vấn đề mà bạn có là tạo một bảng khác, có giá trị thành khóa.

tức là. bạn có 2 bảng có cùng giá trị, một bảng chỉ một hướng, một hướng khác.

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 

Sau đó, bạn có thể truy vấn bảng mới để xem bảng có 'yếu tố' chính hay không. Điều này ngăn cản sự cần thiết phải lặp qua tất cả các giá trị của bảng khác.

Nếu hóa ra bạn không thể sử dụng 'yếu tố' làm khóa, vì đó không phải là chuỗi, sau đó thêm tổng kiểm tra hoặc 'toString' vào ví dụ, sau đó sử dụng nó làm Chìa khóa.

Tại sao bạn muốn thực hiện việc này? Nếu các bảng của bạn rất lớn, thì lượng thời gian lặp lại thông qua mọi phần tử sẽ rất quan trọng, ngăn bạn thực hiện nó rất thường xuyên. Chi phí bộ nhớ bổ sung sẽ tương đối nhỏ, vì nó sẽ lưu 2 con trỏ tới cùng một đối tượng, thay vì 2 bản sao của cùng một đối tượng. Nếu bảng của bạn là rất nhỏ, sau đó nó sẽ quan trọng ít hơn nhiều, Infact nó thậm chí có thể nhanh hơn để lặp lại hơn để có một tra cứu bản đồ.

Từ ngữ của câu hỏi tuy nhiên mạnh mẽ gợi ý rằng bạn có một số lượng lớn các mục cần xử lý.

+0

Một lời giải thích tốt, nhưng không thực sự thêm bất cứ điều gì để thảo luận. Nó có lẽ sẽ là một ý tưởng tốt hơn để chỉnh sửa câu trả lời của interjay. – bcdan

+0

Ngoài ra, '.key' nên được thay thế bằng '[key]' ở mọi nơi trong mã này (giống với 'giá trị') – Njol

Các vấn đề liên quan