C# - Create Enumeraor that Get Values Randomly

846 views Asked by At

I want to create a IEnumerable class in C# that when get next value get it randomly from list of object

I want to get random value each time I want to get next for example I my list length is 100 and I get 1000 times value each time get random value

I create a below class but my program is hanged when create new instance from class

public class MyEnumerable:System.Collections.IEnumerable
{
    public int RegionID { get; set; }

    List<Medium> RankedList;
    MediaEnumerator pe;

    public MyList(int regionID)
    {
        RegionID = regionID;
        RankedList = ShowVideo.GetRankList(regionID);
        pe = new MediaEnumerator(RankedList);
    }

    public System.Collections.IEnumerator GetEnumerator()
    {
        return (IEnumerator)(pe);
    }
}

public class MediaEnumerator : IEnumerator
{
    List<Medium> RankedList;
    int position = -1;

    public MediaEnumerator(List<Medium> list)
    {
        RankedList = list;
    }

    Random rnd = new Random();

    public bool MoveNext()
    {
        position = rnd.Next(RankedList.Count);
        return true;
    }

    public void Reset()
    {
        position = -1;
    }

    object IEnumerator.Current
    {
        get
        {
            return Current;
        }
    }

    public FileInfo Current
    {
        get
        {
            try
            {
                FileInfo fi = new FileInfo(RankedList[position].MediaUrl);
                return fi;
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}
3

There are 3 answers

1
Euphoric On BEST ANSWER

Using iterators with Random and infinite loop would be simplest solution.

public IEnumerable<T> GetRandomElements<T>(T[] elements)
{
    Random rand = new Random();
    while(true)
    {
        int index = rand.Next(0, elements.Length);
        yield return elements[index];
    }
}
2
user4132661 On

I think your problem is that you always return true in MoveNext(), change this codes can may cause to your code work fine

but now there is a error that is the number of get random value is exactly number of your list length. but I fixed your code.

    public bool MoveNext()
    {
        position++;
        return (position < RankedList.Count);
        //position = rnd.Next(RankedList.Count);
        //return true;
    }

and change this code in MediaEnumerator

    public FileInfo Current
    {
        get
        {
            try
            {
                //FileInfo fi = new FileInfo(RankedList[position].MediaUrl);
                FileInfo fi = new FileInfo(RankedList[rnd.Next(RankedList.Count)].MediaUrl);
                return fi;
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
6
Steve Lillis On

You can get any enumerable in a random order by mixing LINQ and GUID.

var randomOrder = originalEnumerable.OrderBy(o => new Guid());