2010-12-02 7 views
1

i ont donc la liste générique suivante:C# Generic List <T> - Comment assigner aléatoirement un "rang" à chaque élément?

var topTenSomething = new List<Something>(); 

Voici Quelque chose:

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

donc je veux assigner au hasard la propriété "Rank", mais il doit être commandé de 1 -nombre d'éléments dans la collection.

Donc, si la collection a 3 articles, je veux assigner au hasard les rangs de 1 à 3:

  1. Certains Nom
  2. Certains Autre nom
  3. Something Else

Puis suivant temps, il pourrait être:

  1. Un autre nom
  2. Certains Nom
  3. Something Else

savoir ce que je veux dire?

Vous ne savez pas comment le faire - des idées?

Ceci est pour un prototype simple R & D - donc ne vous inquiétez pas de la performance/pourquoi je fais cela. (le vrai aura le rang assigné par la base de données)

Heureux avec une version de LINQ/non-LINQ - tant que cela fonctionne.

+0

faire le classement doivent être uniques? –

+0

Voulez-vous que la collection soit triée? – SLaks

+0

@Adam Spicer - oui/ – RPM1984

Répondre

5

Comme ceci:

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

Si vous voulez la liste à trier par le rang au hasard:

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; 

Cependant, ce n'est pas une commande valide (a < b ne signifie pas b > a) et peut provoquer des résultats inattendus.

+1

Je pense que votre OrderBy lamdba cassera le contrat IComparable, quand le même 'i' se retrouve avec des valeurs différentes sur les appels répétés. –

+0

@Joel: Je ne suis pas sûr; Je ne l'ai jamais essayé. Notez que ceci n'est pas directement IComparable. – SLaks

+0

@Joel, ça marche, j'ai fait des choses similaires moi-même pour tester. Ne peut pas jurer par l'implémentation, mais vraisemblablement le résultat lambda de chaque élément est mis en cache afin que les opérations potentiellement coûteuses ne soient pas répétées. –

0

Cela devrait fonctionner:

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

J'ai vu que vous vouliez le trier ensuite. Ajoutez ceci: somethings = somethings.OrderBy (s => s.Rank) .ToList(); –

Questions connexes