2010-04-21 16 views
10

HERE soruma bir göz atıyorum, şimdi kriterlere uyan bir sonraki öneri nesnesini döndürmek istiyorum.LINQ Sonraki Öğe

Öyleyse 10'dan 6'ncı maddeyi buldum, bunun yerine 7. maddeyi döndürmesi için sorguyu istiyorum. Ya da daha iyi bir yolu var mı? Eğer endeksine sahip kez

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

alabilirsiniz: Bir List<T> nesne olduğundan

cevap

14

Eğer ilk eşleşen öğenin dizinini ziyade öğenin kendisini almak için yerine Where onun FindIndex yöntemi kullanabilirsiniz Bir sonraki ürün veya önceki bir ürün veya ne istersen.

+0

+1 SQL için Ters() çalışmaz. –

0

Öğe 7, Where teriminin sizinle eşleşen nesne nedir? Eğer öyleyse, Skip() ve Take() uzatma yöntemleri kullanın:

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

Bunun tam olarak işe yaramayacağını düşünüyorum. OP durumunda, orijinalin sadece 1 sonuç döndüreceği ve ORIGINAL listesindeki bir sonrakileri isteyeceği görülecektir. –

+0

@spoulson, bu doğru. Eşleşen öğeyi bulmak ve listedeki bir sonraki öğeyi döndürmek istiyorum. – griegs

1

Bu yapmalı. Özellikle bunun için bir test yapmamıştım. Her iki kayıtları Gerekirse

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; 

, orada olur (select ifadesi

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

olabilir Ama sonra listedeki son öğeyi olmak eşleşen öğeye hesaba bir gruplandırma yapmak zorunda kalacak Bu durumda bir sonraki öğe olmamalıdır).

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 }; 

Ben Test dizeleri listesiyle benzer bir şeydi yaptım kodu.

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; 

Bu, b, d ve e değerini döndürür. Bir önceki cevabı çalışır Skip(1).Take(1) kullanır

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

, ancak bir sonuç listesini verir:

28

İşte benim şimdiki en iyi yöntem bu. Benim durumumda (ve belki OP'nin vakası), asıl maddeyi arıyoruz. Bu yüzden kodum, aradığımıza kadar geçiyor (bir alt öğeye dönecek olursak, bir sonraki öğeye erişemeyeceğiz), sonra bir tane daha atlıyor ve öğeyi alıyor.

+0

Not: Bu yanıt Microsoft Sanal Akademi kursu 'De-Mystifying LINQ' - Bölüm 6 –

4

böyle bir şey hakkında nasıl

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); 
    } 
} 

Ardından gibi diyebiliriz sizin için nerede

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

bu bir


SONRAKİ Öğe deneyin ediyorum

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

ÖNCEKİ Ürün not: LINQ lambda sözdizimi kullanımı için

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

'Sanırım' Geri 'SQL Server'da uygulanmadı. –

+0

http://msdn.microsoft.com/en-us/library/bb358497(v=vs.110).aspx Bu LINQ ve Tersi burada –

+0

Evet, LINQ API'sı, ancak LINQ to SQL (Server) ise SQL'de herhangi bir eşdeğerlik olmadığından, hata atacaktır. –