테이블에 Lua의 요소가 포함되어 있는지 확인하는 방법은 무엇입니까?


98

테이블에 값이 있는지 확인하는 방법이 있습니까? 나만의 (순진한) 기능이 있지만 "공식적인"기능이 있는지 궁금합니다. 아니면 더 효율적인 것 ...

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

그런데이 함수를 사용하는 주된 이유는 테이블을 세트로 사용하기 위해서입니다. 즉, 중복 요소가 없습니다. 내가 사용할 수있는 다른 것이 있습니까?


3
_, 표기법은 무엇을 의미합니까?
Martin

24
라는 이름의 "가비지"변수 _입니다. pairs()을 반환 key, value하지만이 예제에서는 값만 필요합니다. 필요하지 않은 것을 저장 하기 위해이 변수를 사용 하는 것은 일종의 관례 ( "Programming in Lua" lua.org/pil/index.html 에서 채택 ) _입니다.
Wookai

_파이썬과 자바 스크립트에서 사용되는 "가비지"변수 이름 지정 규칙도 보았습니다 .
iono

답변:


117

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

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

여기에 더 많은 기능을 갖춘 예제가 있습니다 .


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

아마도function keysOfSet(set) local ret={} for k,_ in pairs(set) do ret[#ret+1]=k end return ret end
Jesse Chisholm

24

귀하의 표현이 주어지면 귀하 의 기능은 가능한 한 효율적입니다. 물론 다른 사람들이 언급했듯이 (그리고 Lua보다 오래된 언어로 실행 된 것처럼) 실제 문제에 대한 해결책은 표현을 변경하는 것입니다. 테이블이 있고 세트를 원할 때 세트 요소를 키와 true값 으로 사용하여 테이블을 세트로 변환합니다 . 인터 제이에게 +1.


2

값을 비교하는 다른 방법은 생각할 수 없지만 세트의 요소를 키로 사용하면 값을 nil 이외의 값으로 설정할 수 있습니다. 그러면 전체 테이블을 검색 할 필요없이 빠른 조회를 얻을 수 있습니다.


2

나는 이것이 오래된 게시물이라는 것을 알고 있지만 후손을 위해 무언가를 추가하고 싶었습니다. 당신이 가지고있는 문제를 처리하는 간단한 방법은 중요한 가치의 다른 테이블을 만드는 것입니다.

즉. 하나는 한 방향을 가리키고 다른 하나는 다른 방향을 가리키는 동일한 값을 가진 2 개의 테이블이 있습니다.

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 개의 포인터를 저장하기 때문에 상대적으로 적습니다. 테이블이 매우 작 으면 훨씬 덜 중요합니다. 사실 다른 맵 조회보다 반복하는 것이 더 빠를 수 있습니다.

그러나 질문의 ​​표현은 처리해야 할 항목이 많음을 강력하게 암시합니다.


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

1
또한 '.key'는이 코드의 모든 곳에서 '[key]'로 대체되어야합니다 ( 'value'와 동일)
Njol
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.