2011-01-26 12 views
6

Ho due espressioni LINQ che penso dovrei essere in grado di combinare in una.Esiste un modo migliore per combinare queste due espressioni Linq?

Ho una lista di referrer, ognuno dei quali fa riferimento a più elementi, e sto cercando di determinare gli elementi più popolari. Ogni referente trasmette un punteggio di voto univoco a un articolo referenziato. Cioè, il referrer 1 potrebbe dare un voto di 0.2, e il referrer 2 potrebbe dare un voto di 0.03.

Un semplificata Referrer classe:

class Referrer 
{ 
    public double VoteScore { get; private set; } 
    public List<int> Items { get; private set; } 
    public Referrer(double v) 
    { 
     VoteScore = v; 
     Items = new List<int>(); 
    } 
} 

miei due espressioni Linq sono:

var Votes = 
    from r in Referrers 
    from v in r.Items 
    select new { ItemNo = v, Vote = r.VoteScore }; 

Questo mi dà una lista:

ItemNo:1, Vote:0.2 
ItemNo:3, Vote:0.2 
ItemNo:1, Vote:0.03 

Ora, posso gruppo, somma, e ordinare con la mia seconda espressione:

var SortedByScore = 
    from v in Votes 
    group v by v.ItemNo into g 
    let score = g.Sum((v) => v.Vote) 
    orderby score descending 
    select new { ItemNo = g.Key, Score = score }; 

È possibile combinare questi in una singola espressione? Mi rendo conto che posso concatenare le espressioni, ossia:

var SortedByScore = 
    from v in 
     (from r in ActivatedReferrers 
     from v in r.Items 
     select new { ItemNo = v, Vote = r.VoteScore }) 
    group v by v.ItemNo into g 
    let score = g.Sum((v) => v.Vote) 
    orderby score descending 
    select new { ItemNo = g.Key, Score = score }; 

Ma non è davvero diverso da quello che ho già - è solo la prima nidificazione espressione all'interno del secondo. C'è un altro modo che unisce le due espressioni in una?

+0

Sembra un modello di strano per me. Un "referrer" dà lo stesso punteggio di voto a ciascuna voce nella sua lista di articoli? Mi piacerebbe sapere cosa stai modellando. – Pedro

+0

Pensa a come funziona PageRank. Non è quello che sto costruendo, ma l'idea è simile. Fondamentalmente, ogni referente ottiene un punteggio di 1.0, e quel punteggio è distribuito uniformemente su tutte le cose della sua lista. Il modello è semplice, ma efficace per quello che sto facendo. –

risposta

4

ne dite:

from r in Referrers 
from v in r.Items 
group r.VoteScore by v into g 
let score = g.Sum() 
orderby score descending 
select new { ItemNo = g.Key, Score = score } 
+0

Sembra essere quello che stavo cercando. Grazie. Ora andrò a studiare la sintassi di raggruppamento. Questo è così semplice che mi manca perché non capisco del tutto il raggruppamento. –

+0

Ah, mi sono appena reso conto di cosa sono riuscito a realizzare esattamente quello che hai. Mi sono concentrato maggiormente sulla semplificazione di ciò che Jim aveva e non ho notato che 'Items' era in realtà' List 'che ha cambiato le cose a causa della query nidificata e del riutilizzo della variabile' v'. –

Problemi correlati