2010-12-02 11 views
14

मेरे पास परियोजनाओं की एक सूची है और यदि मैं एक परियोजना का चयन करता हूं तो मैं पिछले और अगले विकल्प का विकल्प दूंगा। मैंने एक त्वरित कोड उदाहरण जोड़ा है लेकिन मुझे आशा है कि ऐसा करने के लिए एक बेहतर/तेज़ तरीका उदाहरण के लिए 500 परियोजनाएं होंगी।लिंक से पहले और वर्तमान में लिंक/सी # के साथ सूची में आइटम कैसे प्राप्त करें?

क्या शायद एक linq विकल्प या कुछ है?

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

त्वरित उदाहरण:

परियोजनाओं एक शब्दकोश

परियोजना एक keyvaluepair कि शब्दकोश में मौजूद है

var match = false; 
var save = new KeyValuePair<ExtendedProjectLightPlan, Page>(); 
var before = new KeyValuePair<ExtendedProjectLightPlan, Page>(); 
var after = new KeyValuePair<ExtendedProjectLightPlan, Page>(); 
foreach (var p in projects) 
{ 
    before = save; 
    save = p; 

    if (match) 
    { 
     after = p; 
     break; 
    } 

    if (p.Key.Id == project.Key.Id) 
    { 
     match = true; 
    }     
} 

उत्तर

13

ऐसा करने के लिए LINQ में कुछ भी नहीं बनाया गया है, लेकिन आप अपना खुद का आसानी से लिख सकते हैं ... यहां एक कार्यान्वयन है जो .NET 4 से Tuple का उपयोग करता है। यह अनुक्रम के लिए n-2 आइटम वापस करेगा जो मूल रूप से n आइटम हैं - लेकिन यदि आवश्यक हो तो आप समायोजित कर सकते हैं।

public IEnumerable<Tuple<T, T, T>> WithNextAndPrevious<T> 
    (this IEnumerable<T> source) 
{ 
    // Actually yield "the previous two" as well as the current one - this 
    // is easier to implement than "previous and next" but they're equivalent 
    using (IEnumerator<T> iterator = source.GetEnumerator()) 
    { 
     if (!iterator.MoveNext()) 
     { 
      yield break; 
     } 
     T lastButOne = iterator.Current; 
     if (!iterator.MoveNext()) 
     { 
      yield break; 
     } 
     T previous = iterator.Current; 
     while (iterator.MoveNext()) 
     { 
      T current = iterator.Current; 
      yield return Tuple.Create(lastButOne, previous, current); 
      lastButOne = previous; 
      previous = current; 
     } 
    }   
} 

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

15

आप IndexOf() और ElementAt() तरीकों का उपयोग कर की कोशिश की है है ??

Int32 index = list1.IndexOf(item); 
    var itemPrev = list1.ElementAt(index - 1); 
    var itemNext = list1.ElementAt(index + 1); 
+0

मेरी गलती, मेरा मतलब है एक शब्दकोश। उदाहरण को पहले से ही – Marco

+1

संपादित करें इस कोड के साथ यदि आइटम पहला तत्व है, यानी इंडेक्स 0 या अंतिम पर, तो आपको अपवाद मिलेगा। –

+2

@ मार्को: शब्दकोश में पहले और बाद में क्या होता है? क्या आप एक ['SortedDictionary'] (http://msdn.microsoft.com/en-us/library/f7fta44c.aspx) का उपयोग कर रहे हैं? –

5

शब्दकोशों में कोई आंतरिक आदेश नहीं है, इसलिए पिछले और अगले आइटम का विचार काफी अधिक गैरकानूनी है।

1

मैं शब्दकोशों में ऑर्डर करने के संबंध में अन्य टिप्पणियों से सहमत हूं। लेकिन चूंकि शब्दकोश IEnumerable<KeyValuePair<K, V>> प्रदान करते हैं, कम से कम, यह कहने के लिए एक छोटा तर्क है कि उनके पास कुछ प्रकार का ऑर्डर है। - और यह बहुत बहुत तेजी से हो जाएगा

var ll = new LinkedList<ExtendedProjectLightPlan>(); 
var qs = 
    from p in projects 
    let node = ll.AddLast(p.Key) 
    select new { Project = p, Node = node, }; 

var lookup = qs.ToDictionary(q => q.Project, q => q.Node); 

var current = (ExtendedProjectLightPlan)null; //Whatever the current one is. 

var previous = lookup[current].Previous.Value; 
var next = lookup[current].Next.Value; 

यह यह बहुत किसी भी परियोजना से पिछले या अगले एक करने के लिए ले जाने के लिए आसान बनाना चाहिए: वैसे भी, यहाँ मेरी सुझाव है। अच्छी तरह से

items.SkipWhile(x => x != current).Skip(1).FirstOrDefault(); 

काम करता है: (गति नहीं एक मुद्दा है, है ना होना चाहिए हालांकि बाद से इस यूआई के लिए है?)

14

मद से पहले 'current': 'current' के बाद

items.TakeWhile(x => x != current).LastOrDefault(); 

आइटम अभिन्न प्रकार के लिए लेकिन अनुक्रम के सिरों पर default(T) वापस कर देगा। आइटम को Nullable<T> पर डालने के लिए उपयोगी हो सकता है ताकि पहले आइटम से पहले, और अंतिम आइटम के बाद null लौटाए।

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

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