LINQ द्वारा सूची में कोई आइटम खोजें?


226

यहां मेरे पास एक सरल उदाहरण है जो स्ट्रिंग की सूची में एक आइटम ढूंढता है। आम तौर पर मैं इसे करने के लिए लूप या अनाम प्रतिनिधि का उपयोग करता हूं:

int GetItemIndex(string search)
{
   int found = -1;
   if ( _list != null )
   {
     foreach (string item in _list) // _list is an instance of List<string>
     { 
        found++;
        if ( string.Equals(search, item) )
        {
           break;
        }
      }
      /* use anonymous delegate
      string foundItem = _list.Find( delegate(string item) {
         found++;
         return string.Equals(search, item);
      });
      */
   }
   return found;
}

LINQ मेरे लिए नया है। मैं उत्सुक हूं कि क्या मैं सूची में आइटम खोजने के लिए LINQ का उपयोग कर सकता हूं? कैसे संभव हो सकता है?


एक दम बढ़िया। हालाँकि, वे सभी लमदा अभिव्यक्ति शैली हैं। मैं यहां एक साधारण सूची का उपयोग करता हूं। सूची कई गुणों के साथ एक वर्ग हो सकती है और कुछ का उपयोग खोज के लिए किया जाता है। तो किसी भी LINQ तरीके को "से .. इन ... इन ... सेलेक्ट ..." की तरह खोजें
David.Chu.ca

नहीं, क्षमा करें। इनमें से अधिकांश विधियाँ (प्रथम, एकल, कोई, ...) सीधे उस रूप में अनुवादित नहीं की जा सकतीं ।
आर। मार्टिनो फर्नांडिस

कोई बात नहीं, वास्तव में आप कुछ मामलों के लिए लंबोदर से छुटकारा पा सकते हैं ...
आर। मार्टिनो फर्नांडिस

शानदार जवाब! मैं सिर्फ एन्यूकरेशन केस से लिनेक की खोज करना चाहता हूं।
डेविड.छु.का।

जवाबों:


478

कुछ तरीके हैं (ध्यान दें कि यह पूरी सूची नहीं है)।

1) एकल एकल परिणाम लौटाएगा, लेकिन अपवाद छोड़ देगा यदि यह एक या एक से अधिक नहीं पाता है (जो आप चाहते हैं या नहीं हो सकता है):

string search = "lookforme";
List<string> myList = new List<string>();
string result = myList.Single(s => s == search);

नोट SingleOrDefault()एक ही व्यवहार करेगा, सिवाय इसके कि संदर्भ के प्रकारों के लिए अशक्त वापस आ जाएगा, या मान के प्रकारों के लिए डिफ़ॉल्ट मान, अपवाद फेंकने के बजाय।

2) आपके मापदंड से मेल खाने वाले सभी आइटम कहां से लौटेंगे, इसलिए आपको एक तत्व के साथ एक IEnumerable मिल सकता है:

IEnumerable<string> results = myList.Where(s => s == search);

3) सबसे पहले पहला आइटम वापस करेगा जो आपके मानदंडों से मेल खाता है:

string result = myList.First(s => s == search);

नोट FirstOrDefault()एक ही व्यवहार करेगा, सिवाय इसके कि संदर्भ के प्रकारों के लिए अशक्त वापस आ जाएगा, या मान के प्रकारों के लिए डिफ़ॉल्ट मान, अपवाद फेंकने के बजाय।


35
बहुत बढ़िया जवाब। मैंने पाया कि मेरी पसंद के जवाब के लिए सिंगलऑर्डेफ़ॉल्ट है - सिंगल के रूप में, लेकिन अगर यह नहीं मिल रहा है तो 'अशक्त' देता है।
एडी पार्कर

2
मैं या तो सिंगल () या सिंगलऑर्डेफ़ॉल्ट () नहीं जानता था। बहुत उपयोगी।
ड्रैकोनिस

क्या इन विधियों का उपयोग अन्य संग्रह जैसे ReadOnlyCollectionया के साथ भी किया जा सकता है ObservableCollection?
येलवोन

@ येलवोन ये किसी भी प्रकार पर विस्तार के तरीके हैं जो लागू होते हैं IEnumerable<T>याIQueryable<T>
Rex M

4
SingleOrDefault का उपयोग करने के बारे में एक बात ध्यान देने योग्य है, क्योंकि यह एक अपवाद को फेंकता है यदि एक से अधिक मिलान सूची में है, तो उसे प्रत्येक आइटम के माध्यम से पुनरावृति करना होगा, जहां FirstOrDefault पहला मैच मिलते ही खोज बंद कर देगा। msdn.microsoft.com/en-us/library/bb342451(v=vs.110).aspx
DavidWainwright

73

यदि आप तत्व का सूचकांक चाहते हैं, तो यह ऐसा करेगा:

int index = list.Select((item, i) => new { Item = item, Index = i })
                .First(x => x.Item == search).Index;

// or
var tagged = list.Select((item, i) => new { Item = item, Index = i });
int index = (from pair in tagged
            where pair.Item == search
            select pair.Index).First();

आप पहले पास में लंबोदर से छुटकारा नहीं पा सकते।

ध्यान दें कि यह फेंक देगा यदि आइटम मौजूद नहीं है। यह अशक्त ints का सहारा लेकर समस्या को हल करता है:

var tagged = list.Select((item, i) => new { Item = item, Index = (int?)i });
int? index = (from pair in tagged
            where pair.Item == search
            select pair.Index).FirstOrDefault();

यदि आप आइटम चाहते हैं:

// Throws if not found
var item = list.First(item => item == search);
// or
var item = (from item in list
            where item == search
            select item).First();

// Null if not found
var item = list.FirstOrDefault(item => item == search);
// or
var item = (from item in list
            where item == search
            select item).FirstOrDefault();

यदि आप मिलान करने वाले आइटमों की संख्या गिनना चाहते हैं:

int count = list.Count(item => item == search);
// or
int count = (from item in list
            where item == search
            select item).Count();

यदि आप सभी आइटम चाहते हैं जो मेल खाते हैं:

var items = list.Where(item => item == search);
// or
var items = from item in list
            where item == search
            select item;

और nullइनमें से किसी भी मामले में सूची की जांच करना न भूलें ।

या के (list ?? Enumerable.Empty<string>())बजाय का उपयोग करें list

टिप्पणियों में मदद करने के लिए पावेल का धन्यवाद।


2
दो बिंदु। सबसे पहले, string.Equalsयहाँ उपयोग करने की कोई वास्तविक आवश्यकता नहीं है - कुछ भी गलत नहीं है ==। दूसरा, मैं यह भी उल्लेख करूंगा कि FirstOrDefault(ऐसे मामलों के लिए जहां आइटम नहीं हो सकता है), और Selectसूचकांक के साथ मामले को कवर करने के लिए जहां आइटम की सूचकांक की जरूरत है (जैसा कि यह स्वयं प्रश्न में नमूने में है)।
पावेल मिनाएव

मैं अभी खुश नहीं हूं। मेरे उदाहरण में कोई -1 इंडेक्स (नहीं मिला) है। कोई उपाय?
आर। मार्टिनो फर्नांडिस

इसके साथ अस्तित्व के लिए जाँच करने के अलावा, पहले।
आर। मार्टिनो फर्नांडिस

क्या मुझे यह जाँचने की आवश्यकता है कि क्या सूची पहले शून्य है?
डेविड.छू.का

ArgumentNullExceptionयदि स्रोत अशक्त है तो थ्रो का चयन करें
आर। मार्टिनो फर्नांडिस

13

यदि यह वास्तव में है, List<string>तो आपको LINQ की आवश्यकता नहीं है, बस उपयोग करें:

int GetItemIndex(string search)
{
    return _list == null ? -1 : _list.IndexOf(search);
}

यदि आप आइटम को स्वयं ढूंढ रहे हैं, तो प्रयास करें:

string GetItem(string search)
{
    return _list == null ? null : _list.FirstOrDefault(s => s.Equals(search));
}

1
पहले उदाहरण के तर्क के बाद, हम _list.Find(search)दूसरे के लिए उपयोग कर सकते हैं ।
jwg

12

क्या आप सूची में आइटम चाहते हैं या वास्तविक आइटम स्वयं (आइटम खुद मान लेंगे)।

यहां आपके लिए विकल्पों का एक गुच्छा दिया गया है:

string result = _list.First(s => s == search);

string result = (from s in _list
                 where s == search
                 select s).Single();

string result = _list.Find(search);

int result = _list.IndexOf(search);

वाह ... कुछ लोग सुपर फास्ट एक ट्रिगर हैं;)
केल्सी

कैसे एक वापसी मूल्य के रूप में सूचकांक के बारे में?
डेविड.छू.का।

और क्या मुझे यह देखने की आवश्यकता है कि क्या _list के रूप में .. के रूप में अशक्त है ...?
डेविड.छु.का

6

यह तरीका आसान और सुरक्षित है

var lOrders = new List<string>();

bool insertOrderNew = lOrders.Find(r => r == "1234") == null ? true : false


1
मुझे लगता है कि हमें true : falseनीचे भी काम करने की ज़रूरत नहीं हैbool insertOrderNew = lOrders.Find(r => r == "1234") == null;
Vbp

5

कैसे के बारे में IndexOf?

निर्दिष्ट ऑब्जेक्ट के लिए खोज करता है और सूची के भीतर पहली घटना का सूचकांक लौटाता है

उदाहरण के लिए

> var boys = new List<string>{"Harry", "Ron", "Neville"};  
> boys.IndexOf("Neville")  
2
> boys[2] == "Neville"
True

ध्यान दें कि यदि सूची में मान नहीं होता है तो यह -1 देता है

> boys.IndexOf("Hermione")  
-1

2

मैं एक डिक्शनरी का उपयोग करता था, जो कि एक अनुक्रमित सूची का कुछ प्रकार होता है, जो मुझे वही देता है जो मैं चाहता हूँ।

Dictionary<string, int> margins = new Dictionary<string, int>();
margins.Add("left", 10);
margins.Add("right", 10);
margins.Add("top", 20);
margins.Add("bottom", 30);

जब भी मैं अपने मार्जिन मूल्यों का उपयोग करना चाहता हूं, उदाहरण के लिए, मैं अपने शब्दकोश को संबोधित करता हूं:

int xStartPos = margins["left"];
int xLimitPos = margins["right"];
int yStartPos = margins["top"];
int yLimitPos = margins["bottom"];

इसलिए, आप जो कर रहे हैं, उसके आधार पर एक शब्दकोश उपयोगी हो सकता है।


एक अलग सवाल का शानदार जवाब।
jwg

2

यहाँ LINQ का उपयोग करने के लिए अपनी विधि को फिर से लिखने का एक तरीका है:

public static int GetItemIndex(string search)
{
    List<string> _list = new List<string>() { "one", "two", "three" };

    var result = _list.Select((Value, Index) => new { Value, Index })
            .SingleOrDefault(l => l.Value == search);

    return result == null ? -1 : result.Index;
}

इस प्रकार, यह साथ बुला रहा है

GetItemIndex("two")लौटेगा 1,

तथा

GetItemIndex("notthere")वापस आ जाएगा -1

संदर्भ: linqsamples.com


1

इस कोड को आज़माएं:

return context.EntitytableName.AsEnumerable().Find(p => p.LoginID.Equals(loginID) && p.Password.Equals(password)).Select(p => new ModelTableName{ FirstName = p.FirstName, UserID = p.UserID });

1

यदि हमें सूची में से एक तत्व खोजने की आवश्यकता है, तो हम Findऔर FindAllएक्सटेंशन विधि का उपयोग कर सकते हैं , लेकिन उनके बीच थोड़ा अंतर है। यहाँ एक उदाहरण है।

 List<int> items = new List<int>() { 10, 9, 8, 4, 8, 7, 8 };

  // It will return only one 8 as Find returns only the first occurrence of matched elements.
     var result = items.Find(ls => ls == 8);      
 // this will returns three {8,8,8} as FindAll returns all the matched elements.
      var result1 = items.FindAll(ls => ls == 8); 

1

यह आपकी Linq सूची खोज में पहला या डिफ़ॉल्ट मान प्राप्त करने में आपकी सहायता करेगा

var results = _List.Where(item => item == search).FirstOrDefault();

यह खोज पहला या डिफ़ॉल्ट मान प्राप्त करेगी जो इसे लौटाएगा।


0

आप ऑब्जेक्ट सूची में ऑब्जेक्ट खोजना चाहते हैं।

यह आपकी Linq सूची खोज में पहला या डिफ़ॉल्ट मान प्राप्त करने में आपकी सहायता करेगा।

var item = list.FirstOrDefault(items =>  items.Reference == ent.BackToBackExternalReferenceId);

या

var item = (from items in list
    where items.Reference == ent.BackToBackExternalReferenceId
    select items).FirstOrDefault();

0

IEnumerable से एक MessageAction वर्ग प्राप्त करने के लिए जहां Linq एक्सटेंशन के साथ आप FirstOfDefault का उपयोग कर सकते हैं। REME

var क्रिया = Message.Actions.Where (e => e.targetByName == className) .FirstOrDefault ();

कहाँ पे

सूची क्रिया {प्राप्त करें; सेट; }

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