कैसे जाँच करें कि क्या वस्तु पहले से ही किसी सूची में मौजूद है


102

मेरे पास एक सूची है

  List<MyObject> myList

और मैं एक सूची में आइटम जोड़ रहा हूं और मैं जांचना चाहता हूं कि क्या वस्तु पहले से ही सूची में है।

इससे पहले कि मैं यह करूँ:

 myList.Add(nextObject);

मैं यह देखना चाहता हूं कि क्या nextObject पहले से ही सूची में है।

ऑब्जेक्ट "MyObject" में कई गुण हैं लेकिन तुलना दो गुणों के मेल पर आधारित है।

"MyObject" की इस सूची में एक नया "MyObject" जोड़ने से पहले सबसे अच्छा तरीका क्या है।

एकमात्र उपाय जो मैंने सोचा था कि एक सूची से एक डिक्शनरी में बदलना है और फिर कुंजी को गुणों का एक संक्षिप्त स्ट्रिंग बनाना है (यह थोड़ा असंतुलित लगता है)।

सूची या LINQ या कुछ और का उपयोग कर किसी भी अन्य क्लीनर समाधान?

जवाबों:


153

यह विशिष्ट स्थिति की जरूरतों पर निर्भर करता है। उदाहरण के लिए, शब्दकोश दृष्टिकोण काफी अच्छा होगा:

  1. सूची अपेक्षाकृत स्थिर है (आवेषण / विलोपन नहीं, जिसके लिए शब्दकोष अनुकूलित नहीं हैं)
  2. सूची काफी बड़ी है (अन्यथा डिक्शनरी का ओवरहेड व्यर्थ है)।

यदि उपरोक्त आपकी स्थिति के लिए सही नहीं हैं, तो बस विधि का उपयोग करें Any():

Item wonderIfItsPresent = ...
bool containsItem = myList.Any(item => item.UniqueProperty == wonderIfItsPresent.UniqueProperty);

यह सूची के माध्यम से गणना करेगा जब तक कि यह एक मैच नहीं मिलता है, या जब तक यह अंत तक नहीं पहुंचता है।


सूची के लिए एक विधेय प्रतिनिधि का उपयोग करें। विशेषज्ञ एक और समाधान नीचे देख रहे हैं, लेकिन यदि आपके पास एक शब्दकोश के साथ विशाल सूचियां और महत्वपूर्ण मूल्य बहुत तेजी से होगा क्योंकि यह एक हैश तालिका है! का आनंद लें
डग

1
एकाधिक मूल्य की जांच कैसे करें?
नितिन करले

80

बस उपयोग करें Contains विधि का । ध्यान दें कि यह समानता फ़ंक्शन के आधार पर काम करता हैEquals

bool alreadyExist = list.Contains(item);

5
यह मेरे लिए काम नहीं किया, यह हमेशा कहा कि यह मौजूद नहीं है
Si8

4
@ Si8 यदि आप वस्तुओं की तुलना करने की कोशिश कर रहे हैं, तो आपको यह सुनिश्चित करना होगा कि IEquatable <T>। आपके कार्यान्वयन को आपके ऑब्जेक्ट के प्रकार के लिए ठीक से लागू किया गया है। अन्यथा, आप ऑब्जेक्ट सामग्री की तुलना नहीं करेंगे। इसमें शामिल अहमद के लिंक को देखें कि इसे कैसे लागू किया जाए।
डग नुड्सन

56

यदि यह उन 2 संपत्तियों का उपयोग करने योग्य है, तो आप कर सकते हैं:

bool alreadyExists = myList.Any(x=> x.Foo=="ooo" && x.Bar == "bat");

7

क्या आप वाकई इस मामले में एक सूची चाहते हैं? यदि आप सूची को कई मदों के साथ आबाद कर रहे हैं, तो प्रदर्शन के साथ myList.Containsया भुगतना होगा myList.Any; रन-टाइम द्विघात होगा। आप एक बेहतर डेटा संरचना का उपयोग करने पर विचार कर सकते हैं। उदाहरण के लिए,

 public class MyClass
    {
        public string Property1 { get; set; }
        public string Property2 { get; set; }

    }

    public class MyClassComparer : EqualityComparer<MyClass>
    {
        public override bool Equals(MyClass x, MyClass y)
        {
            if(x == null || y == null)
               return x == y;

            return x.Property1 == y.Property1 && x.Property2 == y.Property2;
        }

        public override int GetHashCode(MyClass obj)
        {
            return obj == null ? 0 : (obj.Property1.GetHashCode() ^ obj.Property2.GetHashCode());
        }
    }

आप निम्नलिखित तरीके से एक HashSet का उपयोग कर सकते हैं:

  var set = new HashSet<MyClass>(new MyClassComparer());
  foreach(var myClass in ...)
     set.Add(myClass);

बेशक, अगर यह समानता की परिभाषा MyClass'सार्वभौमिक' है, तो आपको एक IEqualityComparerकार्यान्वयन लिखने की ज़रूरत नहीं है ; आप सिर्फ GetHashCodeऔर केवल Equalsकक्षा में ओवरराइड कर सकते हैं ।


हां, वी के लिए बूल मेरा पसंदीदा था। उस मामले के लिए, यह बहुत पहले नहीं था (एह, लगभग 3 सप्ताह) कि हशसेट मेरे लिए उपलब्ध नहीं था क्योंकि मैं 2.0 कोड पर काम कर रहा था, और मैं हशसेट के मोनो कार्यान्वयन में गिरा क्योंकि यह बहुत उपयोगी है :)
जॉन हैना

4

उल्लेख करने के लिए एक और मुद्दा यह है कि आपको यह सुनिश्चित करना चाहिए कि आपकी समानता कार्य जैसा आप उम्मीद करते हैं। आपको बराबर तरीकों पर ओवरराइड करना चाहिए ताकि यह निर्धारित किया जा सके कि आपकी वस्तु के गुणों को समान मानने के लिए दो उदाहरणों के लिए क्या मेल खाना है।

तो फिर तुम सिर्फ mylist.contains (आइटम) कर सकते हैं


3

यहाँ एक त्वरित कंसोल ऐप है जो आपकी समस्या को हल करने की अवधारणा को दर्शाती है।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    public class myobj
    {
        private string a = string.Empty;
        private string b = string.Empty;

        public myobj(string a, string b)
        {
            this.a = a;
            this.b = b;
        }

        public string A
        {
            get
            {
                return a;
            }
        }

        public string B
        {
            get
            {
                return b;
            }
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            List<myobj> list = new List<myobj>();
            myobj[] objects = { new myobj("a", "b"), new myobj("c", "d"), new myobj("a", "b") };


            for (int i = 0; i < objects.Length; i++)
            {
                if (!list.Exists((delegate(myobj x) { return (string.Equals(x.A, objects[i].A) && string.Equals(x.B, objects[i].B)) ? true : false; })))
                {
                    list.Add(objects[i]);
                }
            }
        }
    }
}

का आनंद लें!


3

संपादित करें: मैंने पहली बार कहा था:


शब्दकोश समाधान के बारे में क्या असंगत है। यह मुझे पूरी तरह से सुरुचिपूर्ण लगता है, क्योंकि आपको केवल शब्दकोश के निर्माण में तुलनित्र को स्थापित करने की आवश्यकता है।


बेशक, यह एक कुंजी के रूप में कुछ का उपयोग करने के लिए अयोग्य है जब यह भी मूल्य है।

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


मैं इसका उपयोग केवल तभी करूँगा जब ऑब्जेक्ट्स की सूची इसकी हैश तालिका के बाद से बड़ी थी और वे तेज़ लुकअप के लिए महान हैं।
डग


-1

यदि आप ईएफ कोर ऐड का उपयोग करते हैं

 .UseSerialColumn();

उदाहरण

modelBuilder.Entity<JobItem>(entity =>
        {
            entity.ToTable("jobs");

            entity.Property(e => e.Id)
                .HasColumnName("id")
                .UseSerialColumn();
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.