Mon autre réponse est correcte pour la question, et pourrait être utile dans de nombreux cas, comme se rouler des informations à partir des dés spéciaux (chaque dé de dés est aléatoire, indépendant de l'autre dés). Cependant, vos commentaires le faire sonner comme vous peut être l'espoir d'obtenir une série de "uniques" éléments hors de l' Dictionary
, un peu comme la distribution de cartes à partir d'un pont. Une fois qu'une carte est distribuée, vous ne voulez jamais voir la même carte jusqu'à ce qu'un remaniement. Dans ce cas, la meilleure stratégie dépend exactement ce que vous faites.
Si vous obtenez seulement un certain nombre d'éléments à l'intérieur d'un vaste Dictionary
, alors vous devriez être en mesure d'adapter mon autre réponse, le retrait de l'élément au hasard dans la liste à chaque fois un nouveau est extrait. Vous voudrez aussi de faire la liste dans un LinkedList
, parce que même si ça va être plus lente pour rechercher un élément par son indice, c'est beaucoup moins cher pour supprimer des éléments dans le milieu. Le code pour que cela serait un peu plus compliqué, donc si vous êtes prêt à sacrifier un peu de performance pour plus de simplicité, vous pourriez faire ceci:
public IEnumerable<TValue> UniqueRandomValues<TKey, TValue>(IDictionary<TKey, TValue> dict)
{
Random rand = new Random();
Dictionary<TKey, TValue> values = new Dictionary<TKey, TValue>(dict);
while(values.Count > 0)
{
TKey randomKey = values.Keys.ElementAt(rand.Next(0, values.Count)); // hat tip @yshuditelu
TValue randomValue = values[randomKey];
values.Remove(randomKey);
yield return randomValue;
}
}
Si, d'autre part, vous avez l'intention de tirer un nombre important d'éléments à partir de votre dictionnaire (c'est à dire de traiter plus de log(n) de votre "deck"), vous serez mieux brouiller l'ensemble de votre deck, puis en la tirant par le haut:
public IEnumerable<TValue> UniqueRandomValues<TKey, TValue>(IDictionary<TKey, TValue> dict)
{
// Put the values in random order
Random rand = new Random();
LinkedList<TValue> values = new LinkedList<TValue>(from v in dict.Values
orderby rand.Next()
select v);
// Remove the values one at a time
while(values.Count > 0)
{
yield return values.Last.Value;
values.RemoveLast();
}
}
Le crédit va à ookii.org pour la simple brassage de code. Si ce n'est toujours pas tout à fait à ce que vous recherchez, vous pouvez peut-être commencer une nouvelle question avec plus de détails au sujet de ce que vous essayez de faire.