كيفية التحقق مما إذا كان الجدول يحتوي على عنصر في لوا؟

StackOverflow https://stackoverflow.com/questions/2282444

سؤال

هل هناك طريقة للتحقق مما إذا كان الجدول يحتوي على قيمة؟ لديّ وظيفتي الخاصة (الساذجة) ، لكنني كنت أتساءل عما إذا كان هناك شيء "رسمي" موجود لذلك؟ أو شيء أكثر كفاءة ...

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

بالمناسبة ، السبب الرئيسي في استخدام هذه الوظائف هو استخدام الجداول كمجموعات ، أي مع عدم وجود عناصر مكررة. هل هناك شيء آخر يمكنني استخدامه؟

هل كانت مفيدة؟

المحلول

يمكنك وضع القيم كمفاتيح الجدول. علي سبيل المثال:

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

هناك مثال أكثر ملاءمة بالكامل هنا.

نصائح أخرى

بالنظر إلى تمثيلك ، وظيفتك فعالة بقدر ما يمكن القيام بها. بطبيعة الحال ، كما لاحظ الآخرين (وكما مارسوا بلغات أقدم من لوا) ، فإن الحل لمشكلتك الحقيقية هو تغيير التمثيل. عندما يكون لديك جداول وتريد مجموعات ، تقوم بتحويل الجداول إلى مجموعات باستخدام عنصر تعيين كمفتاح و true كقيمة. +1 إلى interjay.

لا يمكنني التفكير في طريقة أخرى لمقارنة القيم ، ولكن إذا كنت تستخدم عنصر المجموعة كمفتاح ، فيمكنك تعيين القيمة على أي شيء آخر غير NIL. ثم تحصل على بحث سريع دون الحاجة إلى البحث في الجدول بأكمله.

أعلم أن هذا منشور قديم ، لكنني أردت إضافة شيء للأجيال القادمة. الطريقة البسيطة للتعامل مع المشكلة التي لديك هي إنشاء جدول آخر ، ذات قيمة إلى المفتاح.

بمعنى آخر. لديك جدولين لهما نفس القيمة ، أحدهما يشير إلى اتجاه واحد ، أحدهما يشير إلى الآخر.

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 على سبيل المثال ، ثم استخدم ذلك كمفتاح.

لماذا تريد أن تفعل هذا؟ إذا كانت طاولاتك كبيرة جدًا ، فسيكون مقدار الوقت للتكرار من خلال كل عنصر مهمًا ، مما يمنعك من القيام بذلك كثيرًا. ستكون النفقات العامة للذاكرة الإضافية صغيرة نسبيًا ، حيث سيتم تخزين مؤشرتين لنفس الكائن ، بدلاً من نسختين من نفس الكائن. إذا كانت طاولاتك صغيرة جدًا ، فسيكون الأمر أقل أهمية ، فقد يكون الأمر أسرع لتكراره من الحصول على بحث خريطة آخر.

ومع ذلك ، فإن صياغة السؤال تشير بقوة إلى أن لديك عددًا كبيرًا من العناصر التي يجب التعامل معها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top