I am using an extension method which shuffles a generic list. This works
public static void Shuffle<T>(this IList<T> list)
{
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
int n = list.Count;
while (n > 1)
{
byte[] box = new byte[1];
do provider.GetBytes(box);
while (!(box[0] < n * (Byte.MaxValue / n)));
int k = (box[0] % n);
n--;
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
I am trying trying to create another extension method which would utilize Shuffle(), but would shuffle the items in a list in groups based on a defined group size. This method seems to work when debugging the extension method, but the source list in the calling code still contains the original list after the extension call:
public static void GroupRandomize<T>(this IList<T> sourceList, int groupSize)
{
List<T> shuffledList = new List<T>();
List<T> tempList = new List<T>();
int addCounter = 0;
for (int i = 0; i < sourceList.Count; i++)
{
tempList.Add(sourceList[i]);
// if we've built a full group, or we're done processing the entire list
if ((addCounter == groupSize - 1) || (i == sourceList.Count - 1))
{
tempList.Shuffle();
shuffledList.AddRange(tempList);
tempList.Clear();
addCounter = 0;
}
else
{
addCounter++;
}
}
sourceList = shuffledList;
}
How do I ensure the shuffled list is stored properly into the source list?
sourceList is actually a local variable. Might be better to return shuffedList;
var newList = caller.GroupRandomize<T>(5) ;
sourceList = shuffledList;
This will do nothing unless you are using a ref
parameter. You could change your method so that it modifies the sourceList directly:
for(int i = 0; i < sourceList.Length; i++)
sourceList[i] = shuffledList[i];
But I'd recommend changing your approach so that the extension methods return new, shuffled lists, leaving the original lists intact. So instead of:
var list = GetList();
list.Shuffle();
... you would say:
var list = GetList().Shuffle();
Make it a regular method instead of an extension so you can pass it in by reference:
public static void GroupRandomize<T>(ref IList<T> sourceList, int groupSize) {
// ... stuff
sourceList = shuffledList;
}
Or if you don't want to change the header of the method, you could do the something like:
sourceList.Clear();
sourceList.AddRange( shuffledList );
Edit:
As stated by bperniciaro , The AddRange
method is not available in the IList<T>
interface.
StriplingWarrior already suggested an implementation that does what AddRange
would do, so instead I will just improve his answer a little by pointing to another answer , by hvostt , that implements AddRange
as an extension method of IList<T>
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.