यह जांचने के लिए कि लुआ में एक तत्व शामिल है या नहीं?


97

क्या जाँचने की कोई विधि है यदि किसी तालिका में कोई मान है? मेरा अपना (अनुभवहीन) कार्य है, लेकिन मैं सोच रहा था कि क्या इसके लिए कुछ "आधिकारिक" मौजूद है? या कुछ और कुशल ...

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

वैसे, इस फ़ंक्शन का उपयोग करने का मुख्य कारण सेट के रूप में तालिकाओं का उपयोग करना है, अर्थात बिना डुप्लिकेट तत्वों के साथ। क्या कुछ और है जो मैं उपयोग कर सकता हूं?


3
_, संकेतन का क्या अर्थ है?
मार्टिन

24
यह नाम मात्र का "कचरा" चर रहा है _pairs()रिटर्न key, value, लेकिन इस उदाहरण में मुझे केवल मूल्य की आवश्यकता है। यह एक कन्वेंशन की तरह है (इस पुस्तक को "Lua में प्रोग्रामिंग" lua.org/pil/index.html पर अपनाया गया ) इस _चर का उपयोग उन चीजों को संग्रहीत करने के लिए किया जाता है, जिनकी आवश्यकता नहीं है।
वूकाई

मैंने _पायथन और जावास्क्रिप्ट में प्रयुक्त "कचरा" चर नामकरण के सम्मेलन को भी देखा है।
आयनों

जवाबों:


115

आप मानों को तालिका की कुंजी के रूप में रख सकते हैं। उदाहरण के लिए:

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 () एक गलत रिटर्न देता है, हालांकि निर्दिष्ट कुंजी के साथ तालिका में एक आइटम है। लाइन "वापसी सेट [कुंजी] ~ = नील" उस त्रुटि को ठीक करता है।
oers

शायद यह भीfunction keysOfSet(set) local ret={} for k,_ in pairs(set) do ret[#ret+1]=k end return ret end
जेसी चिशोल्म

24

आपके प्रतिनिधित्व को देखते हुए, आपका कार्य उतना ही कुशल है जितना कि किया जा सकता है। बेशक, जैसा कि दूसरों द्वारा नोट किया गया है (और जैसा कि लूआ की तुलना में पुरानी भाषाओं में प्रचलित है), आपकी वास्तविक समस्या का समाधान प्रतिनिधित्व को बदलना है। जब आपके पास टेबल होती है और आप सेट चाहते हैं, तो आप सेट तत्व को कुंजी के trueरूप में और मान के रूप में सेट करके टेबल को सेट करते हैं । इंटर करने के लिए +1।


2

मैं मूल्यों की तुलना करने के लिए दूसरे तरीके के बारे में नहीं सोच सकता, लेकिन यदि आप सेट के तत्व को कुंजी के रूप में उपयोग करते हैं, तो आप शून्य के अलावा किसी भी अन्य के लिए मान सेट कर सकते हैं। तब आपको पूरी तालिका को खोजे बिना तेज़ लुकअप मिल जाता है।


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 पॉइंटर्स स्टोर करेगा। यदि आपकी टेबल बहुत छोटी है, तो यह बहुत कम मायने रखता है, इसे निष्क्रिय करने से भी तेज गति हो सकती है, जबकि एक और नक्शा देखने के लिए।

प्रश्न के शब्दों को दृढ़ता से पता चलता है कि आपके पास निपटने के लिए बड़ी संख्या में आइटम हैं।


एक अच्छी व्याख्या, लेकिन वास्तव में चर्चा के लिए कुछ भी नहीं जोड़ता है। यह शायद अंतरजाल के उत्तर को संपादित करने के लिए एक बेहतर विचार रहा होगा।
बीकानेर

1
इसके अलावा, इस कोड में '
.key
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.