2012-12-11 4 views
7

come è possibile utilizzare gli intervalli raggruppati per uguale o maggiore di?Raggruppa per intervallo utilizzando linq

var data = new[] { 
    new { Id = 0, Price = 2 }, 
    new { Id = 1, Price = 10 }, 
    new { Id = 2, Price = 30 }, 
    new { Id = 3, Price = 50 }, 
    new { Id = 4, Price = 120 }, 
    new { Id = 5, Price = 200 }, 
    new { Id = 6, Price = 1024 }, 
}; 

var ranges = new[] { 10, 50, 100, 500 }; 
var grouped = data.GroupBy(x => ranges.FirstOrDefault(r => r > x.Price)); 

grouped ouput is 
price 10-50 -> 3 
price 50-100 -> 1 
price 100-500 -> 2 

uscita Needed è raggruppato per uguale o superiore alla gamma utilizzata

price >= 10 -> 6 
price >= 50 -> 4 
price >= 100 -> 3 
price >= 500 -> 1 
+0

'100 -> 2' dovrebbe essere' 100 -> 3', poiché sembra che tu usi il conteggio dell'articolo s avendo un prezzo uguale o superiore all'intervallo utilizzato. (Dovresti provare a chiarire la tua domanda a proposito, dal momento che da nessuna parte si menziona una sorta di COUNT) –

+0

@Francis P grazie .. ho modificato il mio post .. Mi serve esattamente il conteggio degli articoli con un prezzo uguale o maggiore della gamma utilizzata . – stackCoder

risposta

10
var grouped = ranges.Select(r => new { 
      Price = r, 
      Count = data.Where(x => x.Price >= r).Count() }); 

E un'altra opzione (se si dispone di dati enorme, quindi il raggruppamento è meglio di enumerare tutti i dati per ogni prezzo gruppo):

var priceGroups = data.GroupBy(x => ranges.FirstOrDefault(r => r > x.Price)) 
         .Select(g => new { Price = g.Key, Count = g.Count() }) 
         .ToList(); 

var grouped = ranges.Select(r => new 
{ 
    Price = r, 
    Count = priceGroups.Where(g => g.Price > r || g.Price == 0).Sum(g => g.Count) 
}); 
+0

grazie risolto il mio problema. @lazyberezovsky – stackCoder

+0

@cosmicgate Non vedo nessuna categoria nella tua domanda. Cos'è quello? –

+0

@cosmicgate mi dispiace, ma un nuovo requisito invalida le risposte correnti. Penso che sia meglio creare una nuova domanda per quello –

1

Raggruppamento partizioni l'origine, ogni elemento è assegnato a un singolo gruppo.

quello che hai è un buon inizio:

var data = new[] { 
    new { Id = 0, Price = 2 }, 
    new { Id = 1, Price = 10 }, 
    new { Id = 2, Price = 30 }, 
    new { Id = 3, Price = 50 }, 
    new { Id = 4, Price = 120 }, 
    new { Id = 5, Price = 200 }, 
    new { Id = 6, Price = 1024 }, 
}; 

var ranges = new[] { 10, 50, 100, 500 }; 
var grouped = data.GroupBy(x => ranges.FirstOrDefault(r => r <= x.Price)); 

seguire con:

int soFar = 0; 
Dictionary<int, int> counts = grouped.ToDictionary(g => g.Key, g => g.Count()); 
foreach(int key in counts.Keys.OrderByDescending(i => i)) 
{ 
    soFar += counts[key]; 
    counts[key] = soFar; 
} 

Oppure, se si vuole fare in una dichiarazione LINQ:

int soFar = 0; 
var grouped = data 
    .GroupBy(x => ranges.FirstOrDefault(r => r <= x.Price)) 
    .OrderByDescending(g => g.Key) 
    .Select(g => 
    { 
    soFar += g.Count(); 
    return new Tuple<int, int>(g.Key, soFar) 
    });