यह निर्धारित करने का सबसे कारगर तरीका है कि क्या Lua तालिका खाली है (जिसमें कोई प्रविष्टियाँ नहीं हैं)?


120

यह निर्धारित करने का सबसे कारगर तरीका है कि क्या कोई तालिका खाली है (यानी, वर्तमान में न तो सरणी-शैली मान और न ही तानाशाही-शैली मूल्य)।

वर्तमान में, मैं उपयोग कर रहा हूँ next():

if not next(myTable) then
    -- Table is empty
end

क्या कोई अधिक कुशल तरीका है?

नोट: #ऑपरेटर यहां पर्याप्त नहीं है, क्योंकि यह केवल तालिका में सरणी-शैली मानों पर काम करता है - इस प्रकार #{test=2}से अप्रभेद्य है #{}क्योंकि दोनों वापस लौटते हैं। 0. यह भी ध्यान दें कि यदि तालिका चर nilनहीं है, तो यह देख लें कि मैं नहीं देख रहा हूँ शून्य मान, बल्कि 0 प्रविष्टियाँ (यानी {}) के साथ तालिकाएँ ।

जवाबों:


151

आपका कोड कुशल है लेकिन गलत है। (विचार करें {[false]=0}।) सही कोड है

if next(myTable) == nil then
   -- myTable is empty
end

अधिकतम दक्षता के लिए आप nextएक स्थानीय चर में बाँधना चाहते हैं , जैसे,

...
local next = next 
...
... if next(...) ...

1
तकनीकी शुद्धता पर अच्छा बिंदु; विशेष मामलों में मैं मूल कोड का उपयोग कर रहा हूं, falseएक अपेक्षित कुंजी नहीं होगी इसलिए if notकाम ठीक है, लेकिन मैं शायद nilभविष्य में इसके बजाय एक अच्छी आदत के रूप में तुलना करने की आदत डालूंगा। और हां, मैं स्पीड के लिए आम यूटिलिटी फंक्शन्स को लोकल वर्जन में बांध रहा हूं। वैसे, इनपुट के लिए धन्यवाद।
अंबर

1
कोड के अनुसार काम करने पर मुझे गलत तरीके से सहमत होना मुश्किल लगता है
RD Alkire

4
हम क्यों कर गति प्राप्त करते हैं local next?
रॉबर्ट

2
@Moberg यह इस कारण से है कि LUA अपने नामस्थान को कैसे संभालता है। बहुत डम्बल डाउन संस्करण, क्या यह पहले स्थानीय तालिकाओं पर चढ़ जाएगा, इसलिए यदि local nextवर्तमान ब्लॉक में है, तो वह इसका उपयोग करेगा, फिर अगले ब्लॉक पर चढ़कर दोहराएगा। एक बार स्थानीय लोगों के बाद, यह केवल ग्लोबल नेमस्पेस का उपयोग करेगा। यह इसका एक डम्बल डाउन संस्करण है, लेकिन अंत में, यह निश्चित रूप से प्रोग्राम गति के संबंध में अंतर का मतलब है।
ATaco

@Moberg ने लुबा ५.२ और ५.३ के संदर्भ में कम डम्बल संस्करण को देखा है, यह है कि गैर स्थानीय लोग या तो अपवाह या _ENV लुकअप हैं। एक उत्थान को अप्रत्यक्ष की एक अतिरिक्त परत से गुजरना पड़ता है, जबकि एक _ENV लुकअप एक टेबल लुकअप है। जबकि वीएम में एक लोकल एक रजिस्टर है
डेमूर रुमेड

1

एक संभावना यह होगी कि तत्व की संख्या को गिनने के लिए, मेटिबिटेबल "newindex" कुंजी का उपयोग करके। जब कुछ नहीं असाइन किया जाता है nil, तो काउंटर बढ़ाएँ (काउंटर के रूप में अच्छी तरह से में रह सकता है) और जब असाइन करते हैं nil, तो काउंटर को घटाएँ ।

खाली तालिका के लिए परीक्षण 0 के साथ काउंटर का परीक्षण करना होगा।

यहां मेटिबिटेबल डॉक्यूमेंटेशन के लिए एक पॉइंटर है

मैं हालांकि आपके समाधान को पसंद करता हूं, और मैं ईमानदारी से यह नहीं मान सकता कि मेरा समाधान कुल मिलाकर तेज है।


5
मूल प्रश्न सिर्फ "सरणी" प्रविष्टियों की गिनती के बारे में नहीं है।
lhf

3
0x6 का सुझाव सरणी-शैली प्रविष्टियों के लिए विशिष्ट नहीं है (न्यूमेरिक संख्यात्मक और गैर-संख्यात्मक दोनों सूचकांकों के लिए काम करता है)। हालांकि, मुख्य मुद्दा का पता लगाया जाएगा जब nilसौंपा गया है, क्योंकि __newindex ट्रिगर नहीं करता है यदि कुंजी पहले से ही तालिका में मौजूद है।
अंबर

3
काम करने के लिए इस ट्रिक के लिए, मेटिबिटेबल को दोनों को लागू करना होगा __indexऔर __newindexएक शैडो टेबल में वास्तविक डेटा को स्टोर करना होगा और असली टेबल को खाली रखना __indexहोगा, ताकि इसे बिल्कुल ही लागू किया जा सके। जोर से सोचकर, मुझे संदेह है कि हर एक लुकअप की बढ़ी हुई लागत इसके लायक नहीं हो सकती है।
RBerteig

0

यह वही है जो आप चाहते थे:

function table.empty (self)
    for _, _ in pairs(self) do
        return false
    end
    return true
end

a = { }
print(table.empty(a))
a["hi"] = 2
print(table.empty(a))
a["hi"] = nil
print(table.empty(a))

आउटपुट:

true
false
true

11
next()अधिक कुशल (और अधिक संक्षिप्त) लूपिंग से अधिक है pairs()
अंबर

8
वास्तव में, अधिक पाशन pairs() है अनिवार्य रूप से बस का उपयोग कर next()तकनीक है, लेकिन अधिक भूमि के ऊपर के साथ।
डबियसजिम

7
इसके अलावा, मानक tableपुस्तकालय में लिखने की अनुशंसा नहीं की जाती है।
टीआई स्ट्रगा

-1

ओवरलोड होने पर __eq के मूल्यांकन से बचने के लिए बेहतर है।

if rawequal(next(myTable), nil) then
   -- myTable is empty
end

या

if type(next(myTable)) == "nil" then
   -- myTable is empty
end

1
मैं एक लुआ नोब समझने की कोशिश कर रहा हूं कि इस उत्तर को क्यों वोट दिया गया था। मैं यह अनुमान लगा रहा हूं कि क्योंकि लुआ में, "अगर दो वस्तुओं में अलग-अलग मेटामेथोड हैं, तो समानता ऑपरेशन के परिणाम झूठे होते हैं, यहां तक ​​कि किसी भी मेटामेथोड को बुलाए बिना"। (यह उद्धरण इस पृष्ठ के निचले भाग में प्रोग्रामिंग से Lua.org पर है )। क्या यह il के लिए ओवरलोडिंग से बचने की आवश्यकता को दूर करता है?
संवत

-1

सर्प प्रयास करो, मेरे लिए काम करो

serpent = require 'serpent'

function vtext(value)
  return serpent.block(value, {comment=false})
end

myTable = {}

if type(myTable) == 'table' and vtext(myTable) == '{}' then
   -- myTable is empty
end

-2

इस बारे में कैसा है ?

if endmyTable[1] == nil then
  -- myTable is empty
end

1
यह एक तालिका पर काम नहीं करेगा जो कि अनुक्रमणिका के रूप में तार के रूप में है
Samhoque

-3

मुझे पता है कि यह पुराना है, और मैं आपको किसी भी तरह से गलत समझ सकता हूं, लेकिन आप सिर्फ यह चाहते हैं कि तालिका खाली हो, जब तक कि आप सिर्फ जाँच कर रहे हैं कि क्या यह है और आप वास्तव में खाली होना चाहते हैं या इसकी आवश्यकता नहीं है, जब तक मैं गलत न समझूँ, आप इसे केवल रीक्रिएट करके इसे साफ़ कर सकते हैं। यह नीचे सिंटैक्स के साथ किया जा सकता है।

yourtablename = {} -- this seems to work for me when I need to clear a table.

4
यह सवाल नहीं है।
यू हाओ

-6

प्रयोग करके देखें #। यह सभी उदाहरणों को वापस करता है जो एक तालिका में हैं। यदि किसी तालिका में उदाहरण नहीं हैं, तो यह वापस आ जाता है0

if #myTable==0 then
print('There is no instance in this table')
end

1
पूछने वाला कहता है कि #यहाँ पर्याप्त नहीं होगा, और कारण देता है; क्या आप बता सकते हैं कि उन कारणों से ऐसा क्यों होता है?
ameed

अच्छा ... मुझे नहीं पता। मैं इसमें नया हूँ इसलिए मुझे पता है कि # # का उपयोग कर रहा है
arthurgps2
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.