2011-12-22 20 views
8

mam IEnumerable<MyData> który zawiera następujące daneLINQ kwerendy, aby wybrać najlepsze rekordy

Fruits | Name | Quantity | 
__________________________ 
Mango | Jay | 10 | 
__________________________ 
Apple | Jay | 16 | 
__________________________ 
Grapes| Jay | 12 | 
__________________________ 
Mango | Raj | 11 | 
__________________________ 
Apple | Raj | 20 | 
__________________________ 
Grapes| Raj | 3  | 
__________________________ 
Mango | Vik | 20 | 
__________________________ 
Apple | Vik | 15 | 
__________________________ 

muszę wybrać z Linq górze dwa ilość według nazwy jak

Jay (10+16+12) = 38 
Raj (11+20+3) = 34 
Vik (20+15) = 35 

Jay i Vik mają dwie najwyższe ilości suma, więc potrzebuję tych rekordów

Fruits | Name | Quantity | 
__________________________ 
Mango | Jay | 10 | 
__________________________ 
Apple | Jay | 16 | 
__________________________ 
Grapes| Jay | 12 | 
__________________________ 
Mango | Vik | 20 | 
__________________________ 
Apple | Vik | 15 | 
__________________________ 
+0

Więc po prostu do wyjaśnienia. Chcesz podsumować ilości na nazwę, znaleźć dwie pierwsze nazwy, a następnie wybrać rekordy z tymi nazwami? – Ray

+0

@Ray: tak, prawo. –

Odpowiedz

11

Brzmi jak możesz coś takiego:

var query = from item in collection 
      group item by item.Name into g 
      orderby g.Sum(x => x.Quantity) descending 
      select g; 
var topTwo = query.Take(2); 

który zabierze pierwszych dwóch grup, więc chcesz go używać jako:

foreach (var group in topTwo) 
{ 
    Console.WriteLine("Name: {0}", group.Key); 
    foreach (var item in group) 
    { 
     Console.WriteLine(" {0}: {1}", item.Fruits, item.Quantity); 
    } 
} 
+1

Dzięki! mój problem został rozwiązany. –

+1

Czy nie należy tego robić według opisu? – Ray

+2

@Ray: Yup - Govind naprawił to dla mnie; dzięki zarówno :) –

0

Wypróbuj następujące:

var topTwo = myData.GroupBy(d => d.Name).OrderByDescending(g => g.Sum(d => d.Quantity)).TakeWhile((data,index) => index < 2).SelectMany(g => g); 
4

coś takiego pracowałbym.

private static IEnumerable<MyData> GetTop2Names(IEnumerable<MyData> data) 
{ 
    var top2 = data.GroupBy(d => d.Name) 
        .OrderByDescending(g => g.Sum(d => d.Quantity)) 
        .Take(2) 
        .Select(g => g.Key); 
    return data.Where(d => top2.Contains(d.Name)); 
} 

Krok po kroku

  1. grupy według nazwy (jak to, co masz zsumowanie)
  2. Sortuj przez sumę ilości
  3. Take 2 najwyższych nazwy
  4. Wybierz elementy z oryginalnej listy pasujące do tych nazw.
+0

+1 bardzo ładne ... bardzo ci dziękuję –

0

powinien wyglądać następująco:

IEnumerable<MyData> source = new List<MyData>(); 
var names = source 
    .GroupBy(item => item.Name) 
    .ToDictionary(item => item.Key, item => item.Sum(i => i.Quantity)) 
    .OrderByDescending(item => item.Value) 
    .Select(item => item.Key) 
    .Take(2); 

var result = source.Where(item => names.Contains(item.Name)); 
Powiązane problemy