2010-12-02 3 views
1

So habe ich die folgende allgemeine Liste:C# Generische Liste <T> - Zufällig zuweisen eines "Rank" zu jedem Artikel?

var topTenSomething = new List<Something>(); 

Hier ist Etwas:

public class Something 
{ 
    public string Name { get; set; } 
    public int Rank { get; set; } 
} 

So möchte ich zufällig den "Rank" Eigenschaft zuweisen, aber es muss von 1 bestellt werden - Anzahl der Objekte in der Sammlung

Wenn also die Sammlung 3 Artikel hat, ich möchte Reihen zufällig zugewiesen werden von 1 bis 3:

  1. Einige Namen
  2. Einige andere Name
  3. Something Else

Dann nächste Zeit könnte es sein:

  1. Ein anderer Name
  2. Einige Namen
  3. Something Else

Wissen Sie, was ich meine?

Nicht sicher, wie es geht - irgendwelche Ideen?

Dies ist für einen einfachen Prototyp R & D - also mach dir keine Sorgen über die Leistung/warum ich das tue. (der echte wird Rang von der Datenbank zugewiesen haben)

Glücklich mit entweder einer LINQ/non-LINQ-Version - solange es funktioniert.

+0

Haben die Rankings eindeutig sein? –

+0

Soll die Sammlung sortiert werden? – SLaks

+0

@Adam Spicer - ja/ – RPM1984

Antwort

5

So:

var rand = new Random(); 
var sequence = Enumerable.Range(0, list.Count).OrderBy(i => rand.Next()).ToList(); 

for(var i = 0; i < list.Count; i++) 
    list[i].Rank = sequence[i]; 

Wenn Sie die Liste nach dem Zufall Rang sortiert werden:

var rand = new Random(); 
list.Sort((a, b) => rand.Next(-1, 2)); //Exclusive upper bound 
for(var i = 0; i < list.Count; i++) 
    list[i].Rank = i; 

Dies ist jedoch keine gültige Ordnung (a < b bedeutet nicht b > a) und kann zu unerwarteten Ergebnissen führen.

+1

Ich denke, Ihr OrderBy lamdba wird den IComparable-Vertrag brechen, wenn das gleiche "i" mit unterschiedlichen Werten bei wiederholten Anrufen endet. –

+0

@Joel: Ich bin mir nicht sicher; Ich habe es nie ausprobiert. Beachten Sie, dass dies nicht direkt IComparable ist. – SLaks

+0

@Joel, es funktioniert, ich habe selbst ähnliche Dinge zum Testen gemacht. Ich kann nicht auf die Implementierung schwören, aber vermutlich wird das Lambda-Ergebnis jedes Elements zwischengespeichert, sodass möglicherweise teure Operationen nicht wiederholt werden. –

0

sollte diese Arbeit:

List<Something> somethings = new List<Something>(); 

/* TODO: populate list here... */ 

Random rand = new Random(); 
somethings.ForEach(s=>s.Rank = rand.Next(1, somethings.Count - 1)); 
+0

Ich sah, du wolltest es danach sortiert. Fügen Sie das hinzu: somethings = somethings.OrderBy (s => s.Rank) .ToList(); –