सूची से खाली स्ट्रिंग्स को कैसे निकालें, फिर किसी सूची से डुप्लिकेट मान निकालें


82

आइए कहते हैं कि मेरे पास तालिका से आने वाले कुछ कॉलम मानों की एक सूची है, मैं खाली स्ट्रिंग और डुप्लिकेट मानों को कैसे निकालूं। कृपया निम्नलिखित कोड देखें:

List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList();

यह वही है जो मैंने अभी-अभी कोड किया है, लेकिन अमीराम का कोड अधिक सुरुचिपूर्ण है, इसलिए मैं उस उत्तर का चयन यहां करूंगा कि यह कैसे है:

DataTable dtReportsList = someclass.GetReportsList();

        if (dtReportsList.Rows.Count > 0)
       { 
           List<string> dtList = dtReportsList.AsEnumerable().Select(dr => dr.Field<string>("column1")).ToList();
           dtList.RemoveAll(x=>x == "");
           dtList = dtList.Distinct().ToList();         

           rcboModule.DataSource = dtList;
           rcboModule.DataBind();               
           rcboModule.Items.Insert(0, new RadComboBoxItem("All", "All"));
       }

समझें कि RemoveAll () dtList को म्यूट करता है; हटाए गए प्रत्येक तत्व सूची में उपयोग किए गए अंतर्निहित सरणी में उच्च सूचकांकों में तत्वों को पुनर्व्यवस्थित करने के लिए सूची को बाध्य करता है। यह तेजी से होगा कि उन्हें छोड़ दें जैसे कि अमीराम अपनी विधि से करता है।
15

जवाबों:


201
dtList  = dtList.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList()

मैंने मान लिया कि खाली स्ट्रिंग और व्हाट्सएप अशक्त की तरह हैं। यदि आप उपयोग नहीं कर सकते हैं IsNullOrEmpty(व्हाट्सएप की अनुमति दें), याs != null


बस एक बात; डिस्टिफ्ट () के साथ डिड्यूपिंग अपेक्षाकृत अक्षम है क्योंकि विधि को सबसे खराब स्थिति का अनुमान लगाना चाहिए।
कीथ्स

@KeithS हम इस डेटा के बारे में क्या जानते हैं Distinctजो इसे अनुकूलित करने की अनुमति नहीं देता है?
14

हम सूची को सॉर्ट कर सकते हैं और फिर यह बता सकते हैं कि यह सॉर्ट किया गया है, जिससे डुप्लिकेटिंग एल्गोरिदम रैखिक हो जाता है; मेरा जवाब देखिए।
कीथ्स

9

अमीराम का उत्तर सही है, लेकिन डिस्टिक्ट () जैसा कि लागू किया गया है एक एन 2 ऑपरेशन है; सूची में प्रत्येक आइटम के लिए, एल्गोरिथम इसकी तुलना पहले से ही संसाधित सभी तत्वों से करता है, और यदि यह अद्वितीय है या इसे अनदेखा करता है तो इसे वापस लौटाता है। हम बेहतर कर सकते हैं।

एक क्रमबद्ध सूची को रैखिक समय में घटाया जा सकता है; यदि वर्तमान तत्व पिछले तत्व के बराबर है, तो इसे अनदेखा करें, अन्यथा इसे वापस कर दें। सॉर्टिंग NlogN है, इसलिए संग्रह को सॉर्ट करने के लिए भी, हमें कुछ लाभ मिलते हैं:

public static IEnumerable<T> SortAndDedupe<T>(this IEnumerable<T> input)
{
   var toDedupe = input.OrderBy(x=>x);

   T prev;
   foreach(var element in toDedupe)
   {
      if(element == prev) continue;

      yield return element;
      prev = element;      
   }
}

//Usage
dtList  = dtList.Where(s => !string.IsNullOrWhitespace(s)).SortAndDedupe().ToList();

यह उन्हीं तत्वों को लौटाता है; वे बस हल कर रहे हैं।


महान। यदि मैं गलत नहीं हूं, तो आप उन तत्वों को पुन: व्यवस्थित करके, जो आप वास्तव में आदेश दे रहे हैं। क्या आप अपने तरीके को "आलसी" बनाने का तरीका सोच सकते हैं?
अमीराम कोरच

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

इसके अलावा, हमारे मामले में, पूरे ऑपरेशन का परिणाम एक सूची है, जिसके लिए "उत्सुक" निष्पादन की आवश्यकता होती है। अगर हम इसके साथ एक IEnumerable के रूप में काम करना चाहते हैं और इसे निष्पादित करना चाहते हैं, तो आप फ़ंक्शन का मांस ले सकते हैं और इसे एक छिपे हुए Iterator वर्ग में रख सकते हैं जो IEnumerable को लागू करता है।
कीथ

Distinctहैशिंग का उपयोग करता है और O (N ^ 2) की तुलना में O (N) के करीब होना चाहिए। स्रोत
रिस्की मार्टिन

... खैर मैं हिम्मत करूँगा, यह वास्तव में करता है; System.Linq.Set एक आंतरिक हैशटेबल डिस्टिंच द्वारा उपयोग किया जाने वाला कार्यान्वयन है, जो O (1) के पास पहुंच समय ग्रहण करने वाला होगा अपने आइटम की GetHashCode () कार्यान्वयन कुशल है और एक समान रूप से वितरित हैश पैदा करता है (डिफ़ॉल्ट कार्यान्वयन ऐसा होता है) । हालाँकि एक हैशटेबल में मेमोरी इश्यूज होते हैं; .NET का मूल कार्यान्वयन दो सरणियों, एक ints और अन्य लिंक किए गए आइटमों का उपयोग करता है, प्रत्येक एक सेट में आइटमों की संख्या के बराबर सबसे अच्छा है और सबसे खराब डबल है।
कीथ्स Ke

1

अमीराम कोरच समाधान वास्तव में सुव्यवस्थित है। यहाँ बहुमुखी प्रतिभा के लिए एक विकल्प है।

var count = dtList.Count;
// Perform a reverse tracking.
for (var i = count - 1; i > -1; i--)
{
    if (dtList[i]==string.Empty) dtList.RemoveAt(i);
}
// Keep only the unique list items.
dtList = dtList.Distinct().ToList();

4
हालांकि यह काम करेगा, जहां क्लॉज तेजी से होता है क्योंकि इसमें इनपुट संग्रह को म्यूट नहीं करना पड़ता है। आप "पारियों" की संख्या को कम कर रहे हैं जो सूची से तत्वों को हटाते समय किया जाना चाहिए, लेकिन इनपुट से कुछ भी नहीं निकालता है; यह उन तत्वों से अधिक है जो मेल नहीं खाते हैं।
15

1

अमीर कोरच के समाधान को सरल बनाने के लिए :

dtList.RemoveAll(s => string.IsNullOrWhiteSpace(s))

डिस्टिंक्ट () या ToList () का उपयोग करने की आवश्यकता नहीं है

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