आइटम को एक सूची से दूसरी सूची में निकालें


206

मैं यह पता लगाने की कोशिश कर रहा हूं कि वस्तुओं की एक सामान्य सूची को कैसे पार करना है जो मैं वस्तुओं की एक अन्य सूची से निकालना चाहता हूं।

तो चलिए बताते हैं कि यह एक काल्पनिक उदाहरण है

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();

मैं list1 को फ़ॉरवर्ड के साथ ट्रेस करना चाहता हूं और List1 में प्रत्येक आइटम को हटाता हूं जो List2 में भी निहित है।

मुझे यकीन नहीं है कि इस बारे में कैसे जाना जा सकता है क्योंकि फॉरेक्स इंडेक्स आधारित नहीं है।


1
आप List1 में आइटम को हटाना चाहते हैं जो List2 में भी हैं?
श्रीनिवास रेड्डी थाटीपार्थी

1
यदि आपके पास list1 = {foo1} और list2 = {foo1, foo1} हो तो क्या होना चाहिए। क्या foo1 की सभी प्रतियों को सूची 2, या सिर्फ पहले से हटा दिया जाना चाहिए?
मार्क बायर्स

2
-1 - मैंने इस प्रश्न के प्रत्येक उत्तर को नीचे कर दिया है क्योंकि मुझे लगा कि वे सभी गलत थे, लेकिन ऐसा प्रतीत होता है कि यह प्रश्न बहुत ही भयावह रूप से पूछा गया है। अब, मैं उन्हें नहीं बदल सकता - माफी। क्या आप उस आइटम को list1उस आइटम से निकालना चाहते हैं जो आप मौजूद हैं list2या आप उस आइटम को list2उस में से निकालना चाहते हैं list1? इस टिप्पणी के समय, प्रदान किया गया प्रत्येक उत्तरार्द्ध प्रदर्शन करेगा।
जॉन रस्च

7
@ जॉन रैशच, आपको उन डाउनवोट्स पर थोड़ा कम ट्रिगर खुश होना चाहिए। कुछ उत्तर काफी वैचारिक हैं और केवल यह दर्शाते हैं कि प्रश्न में उल्लिखित सूचियों से संबंधित बिना ओपी क्या प्राप्त करना चाहता है।
जोहो एंजेलो

3
@ मर्क - आप सही कह रहे हैं, मेरी गलती पूरी तरह से - इसीलिए मैंने यह टिप्पणी करते हुए यहाँ बताया कि क्या हुआ था, मैं एक पिछले उत्तर की खोज कर रहा था जो मुझे पहले से ही इस तरह के एक प्रश्न के बीच में था, मेरे मतदान के बाद और छोड़ने जा रहा था टिप्पणियों के बाद मैंने पाया - यह पता चला है कि इस के लिए सबसे अच्छी प्रक्रिया नहीं है!
जॉन रस्च

जवाबों:


358

आप इसके अलावा उपयोग कर सकते हैं :

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();
List<car> result = list2.Except(list1).ToList();

आपको शायद उन अस्थायी चर की भी आवश्यकता नहीं है:

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();

ध्यान दें कि Exceptया तो सूची को संशोधित नहीं करता है - यह परिणाम के साथ एक नई सूची बनाता है।


13
मामूली बिंदु, लेकिन यह एक उत्पादन करेगा IEnumerable<car>, न कि एक List<car>ToList()सूची वापस लेने के लिए आपको कॉल करना होगा। इसके अलावा, मेरा मानना ​​है कि यह होना चाहिएGetSomeOtherList().Except(GetTheList()).ToList()
एडम रॉबिन्सन

9
using System.Linq;यदि आपके पास पहले नहीं था, तो आपको इसकी आवश्यकता भी होगी ।
येलवोन

1
नोट: list1.Except (सूची 2) list2.Except (सूची 1) के समान परिणाम नहीं देगा। आखिरी ने मेरे लिए काम किया।
मूलांक

2
बस सावधानी बरतें Exceptक्योंकि यह वास्तव में एक सेट ऑपरेशन करता है , जो परिणामी सूची को अलग करता है। मैं इस व्यवहार की उम्मीद नहीं कर रहा था क्योंकि मैं एक का उपयोग कर रहा हूं List, नहीं HashSetसम्बंधित।
लोगन

4
यह कैसे सही उत्तर है? निश्चित रूप से यह आपको अपने संदर्भ में जो आप चाहते हैं वह दे सकता है, हालांकि, "आइटम को एक सूची से दूसरे में निकालें" निश्चित रूप से एक सेट अंतर ऑपरेशन के बराबर नहीं है, और आपको इसे सही उत्तर के रूप में स्वीकार करके लोगों को गलत जानकारी नहीं देनी चाहिए !!!!
user1935724

37

आपको इंडेक्स की आवश्यकता नहीं है, क्योंकि List<T>क्लास आपको Removeफ़ंक्शन का उपयोग करके इंडेक्स के बजाय आइटम द्वारा मूल्य निकालने की अनुमति देती है।

foreach(car item in list1) list2.Remove(item);

3
+1, लेकिन IMO आपको list2.Remove(item);कथन के चारों ओर कोष्ठक का उपयोग करना चाहिए ।
ANEves

2
@ एसटीआर पीटी: मैं हमेशा उन बयानों पर ब्रैकेट का उपयोग करता हूं जो किसी अन्य लाइन पर दिखाई देते हैं, लेकिन एकल-स्टेटमेंट ब्लॉक पर नहीं जो मैं प्रवाह नियंत्रण कथन के समान लाइन पर जगह बना सकता हूं / कर सकता हूं।
एडम रॉबिन्सन

4
@uriz: क्या सुरुचिपूर्ण होगा की योग्यता की उपेक्षा, यह एकमात्र उत्तर है जो वास्तव में वही करता है जो सवाल कहता है (मुख्य सूची में आइटम हटाता है); अन्य उत्तर एक नई सूची बनाता है , जो वांछनीय नहीं हो सकता है यदि सूची को एक अलग कॉलर से पारित किया जा रहा है जो प्रतिस्थापन सूची प्राप्त करने के बजाय इसे संशोधित करने की उम्मीद कर रहा है।
एडम रॉबिन्सन

5
@uriz @AdamRobinson जब से हम सुरुचिपूर्ण समाधानों पर चर्चा कर रहे हैं ...list1.ForEach(c => list2.Remove(c));
डेविड शेरेट

1
"सुरुचिपूर्ण" का अर्थ होना चाहिए "इस कोड को बनाए रखने वाले डेवलपर को यह सरल और समझने में आसान लगेगा," यही कारण है कि यह सबसे अच्छा जवाब है।
सेठ

22

मैं LINQ एक्सटेंशन विधियों का उपयोग करने की सलाह दूंगा । आप आसानी से कोड की एक पंक्ति के साथ ऐसा कर सकते हैं:

list2 = list2.Except(list1).ToList();

यह निश्चित रूप से सूची 1 में उन वस्तुओं को मान रहा है जिन्हें आप सूची 2 से हटा रहे हैं।


2
यह डुप्लिकेट को भी हटाता है।
जुलाईऑर्डिनरी

17

मेरे मामले में मेरे पास दो अलग-अलग सूचियां थीं, एक सामान्य पहचानकर्ता के साथ, एक विदेशी कुंजी की तरह। "Nzrytmn" द्वारा उद्धृत दूसरा समाधान :

var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();

क्या वह मेरी स्थिति में सबसे उपयुक्त था। मुझे रिकॉर्ड के बिना एक ड्रॉपडाउनलिस्ट लोड करने की आवश्यकता थी जो पहले से ही पंजीकृत थी।

धन्यवाद !!!

यह मेरा कोड है:

t1 = new T1();
t2 = new T2();

List<T1> list1 = t1.getList();
List<T2> list2 = t2.getList();

ddlT3.DataSource= list2.Where(s => !list1.Any(p => p.Id == s.ID)).ToList();
ddlT3.DataTextField = "AnyThing";
ddlT3.DataValueField = "IdAnyThing";
ddlT3.DataBind();

ou ने कभी यह नहीं बताया कि DDlT3 क्या था
rogue39nin'

15

आप LINQ का उपयोग कर सकते हैं, लेकिन मैं RemoveAllविधि के साथ जाऊंगा । मुझे लगता है कि वह वही है जो आपके इरादे को बेहतर ढंग से व्यक्त करता है।

var integers = new List<int> { 1, 2, 3, 4, 5 };

var remove = new List<int> { 1, 3, 5 };

integers.RemoveAll(i => remove.Contains(i));

9
या विधि समूहों के साथ और भी सरल - आप कर सकते हैं - पूर्णांक। RemoveAll (remove.Contains);
रयान

12
list1.RemoveAll(l => list2.Contains(l));

उर्फ "पूरी तरह से अशुद्ध" :-)
एक्सन-कुन क्लार्क-डेविस

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

1
चूँकि दोनों सूची विधियाँ हैं O(N), इसलिए यह O(N^2)बड़ी सूची के साथ एक मुद्दा हो सकता है।
बाघिन

7

समाधान 1: आप इस तरह कर सकते हैं:

List<car> result = GetSomeOtherList().Except(GetTheList()).ToList();

लेकिन कुछ मामलों में यह समाधान काम नहीं कर सकता है। अगर यह काम नहीं करता है तो आप मेरे दूसरे समाधान का उपयोग कर सकते हैं।

समाधान 2:

List<car> list1 = GetTheList();
List<car> list2 = GetSomeOtherList();

हम दिखावा करते हैं कि सूची 1 आपकी मुख्य सूची है और सूची 2 आपकी दूसरी सूची है और आप सूची 2 की वस्तुओं के बिना सूची 1 के आइटम प्राप्त करना चाहते हैं।

 var result =  list1.Where(p => !list2.Any(x => x.ID == p.ID && x.property1 == p.property1)).ToList();

0

के रूप में Exceptसूची में बदलाव नहीं है, तो आप उपयोग कर सकते हैं foreach पर List<T>:

list2.ForEach(item => list1.Remove(item));

यह सबसे कुशल तरीका नहीं हो सकता है, लेकिन यह सरल है, इसलिए पठनीय है, और यह मूल सूची (जो मेरी आवश्यकता है) को अपडेट करता है।


-3

ये रहा..

    List<string> list = new List<string>() { "1", "2", "3" };
    List<string> remove = new List<string>() { "2" };

    list.ForEach(s =>
        {
            if (remove.Contains(s))
            {
                list.Remove(s);
            }
        });

3
-1। पहला आइटम हटाए जाने के बाद यह अपवाद छोड़ देगा। इसके अलावा, यह (आम तौर पर) सूची को निकालने के लिए एक बेहतर विचार है , क्योंकि यह आमतौर पर छोटा होता है। आप इस तरह से और अधिक सूची ट्रैवर्स मजबूर कर रहे हैं।
एडम रॉबिन्सन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.