2010-02-17 5 views
74

테이블에 값이 있는지 확인하는 방법이 있습니까? 내 자신의 (순진) 기능을 가지고 있지만, 뭔가 "공식적인"그것에 대한 존재하는지 궁금 해서요? 또는 더 효율적 뭔가 ... 그런데테이블에 루아에 요소가 있는지 확인하는 방법?

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

, 나는이 기능을 사용하고 주된 이유는 즉 아무 중복 요소, 세트로 테이블을 사용하는 것입니다. 내가 사용할 수있는 다른 것이 있습니까?

+2

_ 기호는 무엇을 의미합니까? – Martin

+18

단순히 "_"라는 "쓰레기"변수 일뿐입니다. 'pairs()'는'key, value'를 반환하지만,이 예제에서는 값만 필요합니다. 이'_' 변수를 사용하여 필요없는 것을 저장하는 것은 일종의 관례입니다 ("Programming in Lua"http://www.lua.org/pil/index.html). – Wookai

답변

91

값을 테이블의 키로 넣을 수 있습니다. 예 :

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 

더 많은 기능을 갖춘 here이 있습니다.

+12

익명 사용자가 코드에 다음 수정 사항을 제안했습니다. 지정된 키가있는 집합의 값이 FALSE이면 지정된 키가있는 테이블에 항목이 있지만 setContains() 함수는 false를 반환합니다. "return set [key] ~ = nil"줄은 오류를 수정합니다. – oers

2

값을 비교하는 다른 방법은 생각할 수 없지만 집합의 요소를 키로 사용하면 값을 nil 이외의 값으로 설정할 수 있습니다. 그런 다음 전체 테이블을 검색하지 않고도 빠른 조회를 수행 할 수 있습니다.

22

표현이 주어지면 귀하의 기능은 수행 할 수있는만큼 효율적입니다. 물론 다른 사람들이 언급 한 것처럼 (그리고 루아보다 오래된 언어로 연습 한 것처럼), 실제 문제에 대한 해결책은 표현을 변경하는 것입니다. 테이블이 있고 세트가 필요하면 set 요소를 키로 사용하고 값으로 true을 사용하여 테이블을 세트로 변환합니다. +1 interjay.

0

나는 이것이 오래된 게시물 인 것을 알고 있지만 후세를 위해 뭔가를 추가하고 싶다. 당신이 가지고있는 문제를 처리하는 간단한 방법은 키 값을 가진 다른 테이블을 만드는 것입니다.

즉. 같은 값을 가진 두 개의 테이블이 있습니다. 한 테이블은 한 방향을 가리키고, 한 테이블은 다른 테이블을 가리 킵니다.

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 

그런 다음 새 테이블에 쿼리하여 '요소'키가 있는지 확인할 수 있습니다. 이렇게하면 다른 테이블의 모든 값을 반복 할 필요가 없습니다.

예를 들어 문자열이 아니기 때문에 실제로 '요소'를 키로 사용할 수 없다는 것이 판명되면 체크섬 또는 'toString'을 추가 한 다음 해당 요소를 키.

왜이 작업을 수행 하시겠습니까? 테이블이 매우 큰 경우 모든 요소를 ​​반복하는 데 필요한 시간이 중요하므로 자주 수행하지 못할 수 있습니다. 추가 메모리 오버 헤드는 비교적 작을 것입니다. 동일한 객체에 대해 2 개의 사본이 아니라 동일한 객체에 2 개의 포인터를 저장하기 때문입니다. 테이블이 매우 작 으면 문제가 훨씬 적어지며 다른 맵을 조회하는 것보다 반복하는 것이 더 빠를 수도 있습니다.

그러나 질문의 ​​말씨는 다루어야 할 항목이 많다는 것을 강력하게 암시합니다.

+0

좋은 설명이지만 실제로 토론에 아무 것도 추가하지는 않습니다. interjay의 대답을 편집하는 것이 더 좋은 생각이었을 것입니다. – bcdan

+0

또한 '.key'는이 코드의 '[key]'로 대체해야합니다 ('value'와 동일). – Njol