केवल सूची में अद्वितीय आइटम जोड़ें


84

मैं दूरस्थ उपकरणों को एक सूची में जोड़ रहा हूं क्योंकि वे पूरे नेटवर्क में खुद की घोषणा करते हैं। मैं केवल डिवाइस को सूची में जोड़ना चाहता हूं यदि यह पहले नहीं जोड़ा गया है।

घोषणाएं एक async सॉकेट श्रोता पर आ रही हैं, ताकि एक डिवाइस को जोड़ने के लिए कोड को कई थ्रेड पर चलाया जा सके। मुझे यकीन नहीं है कि मैं क्या गलत कर रहा हूं, लेकिन कोई मैटर नहीं है जो मैं कोशिश करता हूं मैं दोहराव के साथ समाप्त होता हूं। यहाँ मेरे पास वर्तमान में क्या है .....

lock (_remoteDevicesLock)
{
    RemoteDevice rDevice = (from d in _remoteDevices
                            where d.UUID.Trim().Equals(notifyMessage.UUID.Trim(), StringComparison.OrdinalIgnoreCase)
                            select d).FirstOrDefault();
     if (rDevice != null)
     {
         //Update Device.....
     }
     else
     {
         //Create A New Remote Device
         rDevice = new RemoteDevice(notifyMessage.UUID);
         _remoteDevices.Add(rDevice);
     }
}

किसकी परिभाषा है RemoteDevice?
pstrjds

डीबगिंग उद्देश्यों के लिए, क्या आप टाइमस्टैम्प क्षेत्र के साथ अपने _remoteDevices वर्ग का विस्तार कर सकते हैं, _remoteDevices.lastSeen = अब?
बेथ

जवाबों:


154

यदि आपकी आवश्यकताओं में कोई डुप्लिकेट नहीं है, तो आपको हैशसेट का उपयोग करना चाहिए ।

HashSet.Add वापस आ जाएगी झूठी जब आइटम पहले से मौजूद है (यदि यह है कि आप के लिए मायने रखती है)।

आप समानता ऑपरेटर को परिभाषित करने के लिए नीचे (या यहाँ ) लिंक के निर्माणकर्ता का उपयोग कर सकते हैं या आपको RemoteDevice( GetHashCodeऔर Equals) में समानता विधियों को लागू करने की आवश्यकता होगी ।


3
इस उत्तर को जोड़ने वाला था। तुलना को परिभाषित करने के लिए आप इस अधिभार का उपयोग कर सकते हैं - msdn.microsoft.com/en-us/library/bb359100(v=vs.100).aspx
pstrjds

11
यहाँ एक महत्वपूर्ण बात यह है कि हैशसेट को प्रविष्टि आदेश का सम्मान करने की गारंटी नहीं है। इसलिए यदि ऑर्डर महत्वपूर्ण है (आइटम को उसी क्रम में सूची में प्रदर्शित करने की आवश्यकता है जैसा कि आप उन्हें डालते हैं, जैसे कि क्या होता है List<T>) तो हैशसेट अच्छी तरह से काम नहीं करता है।
जूलियनआर

इसके लिए बहुत धन्यवाद। क्या मुझे अभी भी थ्रेड सुरक्षा के लिए लॉक रखने की आवश्यकता है या कोई बेहतर तरीका है?
ओली

2
@ ओली आपको लॉक रखने की आवश्यकता है, लेकिन ऑपरेशन बहुत तेज होगा, इसलिए वे एक-दूसरे पर उतना इंतजार नहीं करेंगे। कोई ConcurrentSetवर्ग नहीं है , दुर्भाग्य से। हालांकि एक ConcurrentDictionaryवर्ग है, इसलिए आप इसका उपयोग कर सकते हैं, अपने मूल्यों को कुंजी के रूप में संग्रहीत करें और मूल्यों में संग्रहीत करें null
सर्विस

1
@ ओली: अगर मैं आप होते, तो मैं उस मुद्दे को संबोधित करने के लिए एक और प्रश्न पोस्ट करता (दोनों GetHashCode & Equals के पूर्ण स्रोत के साथ, उन मामलों के साथ जहां वे मैच करते हैं जब आप उनसे उम्मीद नहीं करते हैं)।
ऑस्टिन सैलूनन

22
//HashSet allows only the unique values to the list
HashSet<int> uniqueList = new HashSet<int>();

var a = uniqueList.Add(1);
var b = uniqueList.Add(2);
var c = uniqueList.Add(3);
var d = uniqueList.Add(2); // should not be added to the list but will not crash the app

//Dictionary allows only the unique Keys to the list, Values can be repeated
Dictionary<int, string> dict = new Dictionary<int, string>();

dict.Add(1,"Happy");
dict.Add(2, "Smile");
dict.Add(3, "Happy");
dict.Add(2, "Sad"); // should be failed // Run time error "An item with the same key has already been added." App will crash

//Dictionary allows only the unique Keys to the list, Values can be repeated
Dictionary<string, int> dictRev = new Dictionary<string, int>();

dictRev.Add("Happy", 1);
dictRev.Add("Smile", 2);
dictRev.Add("Happy", 3); // should be failed // Run time error "An item with the same key has already been added." App will crash
dictRev.Add("Sad", 2);

16

जैसे स्वीकृत उत्तर कहता है कि हाशसेट के पास कोई आदेश नहीं है। यदि आदेश महत्वपूर्ण है, तो आप एक सूची का उपयोग करना जारी रख सकते हैं और जांच कर सकते हैं कि क्या इसमें आइटम है इससे पहले कि आप इसे जोड़ते हैं।

if (_remoteDevices.Contains(rDevice))
    _remoteDevices.Add(rDevice);

कस्टम वर्ग / ऑब्जेक्ट पर List.Contains () निष्पादित करना कस्टम क्लास IEquatable<T>पर लागू करने या ओवरराइड करने की आवश्यकता है EqualsGetHashCodeकक्षा में भी इसे लागू करना एक अच्छा विचार है । यह https://msdn.microsoft.com/en-us/library/ms224763.aspx पर प्रलेखन के अनुसार है

public class RemoteDevice: IEquatable<RemoteDevice>
{
    private readonly int id;
    public RemoteDevice(int uuid)
    {
        id = id
    }
    public int GetId
    {
        get { return id; }
    }

    // ...

    public bool Equals(RemoteDevice other)
    {
        if (this.GetId == other.GetId)
            return true;
        else
            return false;
    }
    public override int GetHashCode()
    {
        return id;
    }
}

हाय thx, लेकिन क्या होगा अगर आप ओवरराइड नहीं कर सकते क्योंकि मैं किसी और के कोड के संदर्भ का उपयोग कर रहा हूं - यहां कोई क्या करता है?
BKSpurgeon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.