I recently started in C# and am working on a program for which I need to drop n
random values from a dictionary. I picked up some code from this previous q&a and added DropRandom
to remove n
values, but when I run DropRandom
(say with keepN = 10
) the dictionary doesn't drop directly to 10 values.
For example, from a total initial count of 100 with a desired final count of 10, the count might drop to 20. I can run DropRandom
on the resulting Dictionary, and it will then drop to 12, and finally a third (or fourth or fifth...) iteration will take it down to a count of 10.
So my question is, what can I do to get DropRandom
to immediately drop to the desired count?
The first part of things merely sets up the random keys (adapted from above mentioned q&a):
public static IEnumerable<TKey> RandomKeys<TKey, TValue>(IDictionary<TKey,TValue> dictionary)
{
Random random = new Random();
List<TKey> keys = Enumerable.ToList(dictionary.Keys);
int size = dictionary.Count();
while (true) //returns random order of keys from dictionary using infinite loop
{
yield return keys[random.Next(size)];
}
}
The second part removes all but n
values:
public static void DropRandom<TKey, TValue>(int keepN, ref Dictionary<TKey, TValue> dictionary)
{
if(dictionary.Count() < keepN)
{
throw new Exception("Trying to keep more items than in dictionary");
}
Console.WriteLine("old dict size = " + dictionary.Count());
Dictionary<TKey, TValue> tempDict = new Dictionary<TKey, TValue>();
//inelegant way to get extra values...
IEnumerable<TKey> randK = RandomKeys(dictionary).Take(keepN * 2);
while (tempDict.Count() < keepN)
{
foreach(TKey key in randK)
{
if (!tempDict.ContainsKey(key))
{
tempDict.Add(key, dictionary[key]);
Console.WriteLine("key = " + key.ToString());
}
}
}
dictionary = null;
dictionary = tempDict;
Console.WriteLine("New dict size = " + dictionary.Count());
}