2010-04-21 21 views
10

मेरे प्रश्न HERE पर एक नज़र डालने पर, अब मैं मानदंडों से मेल खाने वाले अगले अनुशंसा ऑब्जेक्ट (बाद) को वापस लौटना चाहता हूं।LINQ सूची में अगला आइटम

तो कहें कि मुझे 10 में से 6 आइटम मिला, मैं चाहता हूं कि क्वेरी 7 आइटम लौटाए।

या क्या कोई बेहतर तरीका है?

int index = recommendations.FindIndex(rp => 
              rp.Products.Any(p => p.Product.Code == "A") 
             && rp.Products.Any(p => p.Product.Code == "B") 
            ); 

एक बार जब आप सूचकांक है आप प्राप्त कर सकते हैं:

उत्तर

14

चूंकि आप एक List<T> वस्तु है आप के बजाय स्वयं आइटम पहले मिलान के आइटम के सूचकांक पाने के लिए Where के बजाय अपने FindIndex विधि का उपयोग कर सकते हैं अगली वस्तु या पिछली वस्तु या जो कुछ भी आप चाहते हैं।

+0

+1 लैम्ब्डा वाक्य रचना के उपयोग के लिए रिवर्स() काम नहीं करेगा। –

0

क्या आइटम 7 आपके क्लॉज के लिए एक मैच है? यदि हां, तो Skip() और Take() विस्तार तरीकों का उपयोग:

var myProducts = 
    from rp in recommendations 
    where 
     cp.Products.Any(p => p.Product.Code == "A") && 
     cp.Products.Any(p => p.Product.Code == "B") 
    select rp; 

var nextProduct = myProducts.Skip(1).Take(1); 
+0

मुझे नहीं लगता कि यह वास्तव में काम करेगा। ओपीएस मामले में ऐसा लगता है कि मूल केवल 1 परिणाम लौटाएगा, और वे अगली मूल सूची में चाहते हैं। –

+0

@ स्पॉल्सन, यह सही है। मैं मिलान करने वाला आइटम ढूंढना चाहता हूं और फिर सूची में अगला आइटम वापस भेजना चाहता हूं। – griegs

1

यह यह करना चाहिए। मैंने विशेष रूप से इसके लिए एक परीक्षण का निर्माण नहीं किया है।

var nextProducts = from item1 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx }) 
        join item2 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx }) 
        on item1.Index equals item2.Index - 1 
        where item1.Rec.Products.Any(p => p.Code == "A") 
        && item1.Rec.Products.Any(p => p.Code == "B") 
        select item2.Rec; 

आप दोनों रिकॉर्ड की जरूरत है, तो चयन बयान

select new { MatchingItem = item1.Rec, NextItem = item2.Rec }; 

हो सकता है लेकिन तब आप उससे मिलते-जुलते आइटम सूची में अंतिम आइटम जा रहा है के लिए खाते में करने के लिए एक समूह ऐसा करने के लिए होगा (वहाँ होगा उस मामले में कोई अगली वस्तु न हो)।

var nextProducts = from item1 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx }) 
        join item2 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx }) 
        on item1.Index equals item2.Index - 1 
        into groupjoin 
        from i2 in groupjoin.DefaultIfEmpty() 
        where item1.Rec.Products.Any(p => p.Code == "A") 
        && item1.Rec.Products.Any(p => p.Code == "B") 
        select new { MatchingItem = item1.Rec, NextItem = i2 == null ? null : i2.Rec }; 

कोड मैं किया परीक्षण स्ट्रिंग की एक सूची के साथ कुछ ऐसा ही था।

List<string> list = new List<string>() { "a", "b", "c", "a", "d", "a", "e" }; 

var query = from item1 in list.Select((s, idx) => new { Item = s, Index = idx }) 
      join item2 in list.Select((s, idx) => new { Item = s, Index = idx }) 
      on item1.Index equals item2.Index - 1 
      where item1.Item == "a" 
      select item2.Item; 

जो बी, डी, और ई देता है।

MyList.SkipWhile(item => item.Name != "someName").Skip(1).FirstOrDefault() 

एक पहले जवाब Skip(1).Take(1) जो काम करता है का उपयोग करता है, लेकिन एक परिणाम की एक सूची देता है:

28

यहाँ मेरे वर्तमान का सबसे अच्छा तरीका है। मेरे मामले में (और शायद ओपी का मामला), हम वास्तविक वस्तु की तलाश में हैं। तो मेरा कोड तब तक छोड़ देता है जब तक कि हम उस व्यक्ति तक नहीं पहुंच जाते जिसे हम ढूंढ रहे हैं (जहां एक सबसेट वापस आ जाएगा, इसलिए हमें अगले आइटम तक पहुंच नहीं होगी) फिर एक और छोड़ देता है और फिर आइटम प्राप्त करता है।

+0

नोट: यह उत्तर माइक्रोसॉफ्ट वर्चुअल अकादमी कोर्स 'डी-माइस्टिफाइंग LINQ' में उल्लिखित है - भाग 6 –

4

कैसे कुछ इस तरह के बारे में:

public static class Extension 
{ 
    public static T Next<T>(this IEnumerable<T> source, Func<T, bool> predicate) 
    { 
     bool flag = false; 

     using (var enumerator = source.GetEnumerator()) 
     { 
      while (enumerator.MoveNext()) 
      { 
       if (flag) return enumerator.Current; 

       if(predicate(enumerator.Current)) 
       { 
        flag = true; 
       } 
      } 
     } 
     return default(T); 
    } 
} 

फिर आप इसे पसंद कह सकते हैं आप के लिए कहाँ

Products.Next(x => x.Whatever); 
3

यह एक


अगले आइटम का प्रयास करेंगे

MyList.SkipWhile(x => x != value).Skip(1).FirstOrDefault(); 

पिछले आइटम ध्यान दें: LINQ SQL करने के लिए

var MyList2 = MyList.ToList(); 
MyList2.Reverse(); 
MyList2.SkipWhile(x => x != value).Skip(1).FirstOrDefault(); 
+0

मुझे लगता है कि SQL सर्वर में 'रिवर्स' लागू नहीं किया गया है। –

+0

http://msdn.microsoft.com/en-us/library/bb358497(v=vs.110).aspx यह LINQ और रिवर्स है –

+0

हां, यह LINQ API है, लेकिन यदि यह LINQ से SQL (सर्वर) है , यह त्रुटि फेंक देगा, क्योंकि एसक्यूएल में कोई समानता नहीं है। –

संबंधित मुद्दे