I have a List of 10,000 entries of type Element
:
public class Element
{
public Element()
{
this.Id = Guid.NewGuid();
}
public Guid Id { get; set };
}
And I have another List of 5,000 entries of type Link
:
public class Link
{
public Link(Guid ElementOne, Guid ElementTwo)
{
this.ElementOne = ElementOne;
this.ElementTwo = ElementTwo;
}
public Guid ElementOne { get; set; }
public Guid ElementTwo { get; set; }
}
I am populating my Lists here:
for (int i = 0; i < 10,000; i++)
this.ListOfElements.Add(new Element());
for (int i = 0; i < 5,000; i++)
{
this.ListOfLinks.Add(new Link(need ElementOne, need ElementTwo));
}
I am not sure what to pass for ElementOne
and ElementTwo
. I want to grab a random Id from the Element List ( Element.Id
) for both parameters and ensure they're unique ( ElementOne
could never be ElementTwo
).
Sounds like you just need two random numbers. You can compare and repoll if you happen to get a duplicate.
for (int i = 0; i < 5,000; i++)
{
int ele1 = Random.NextInt(10000);
int ele2 = Random.NextInt(10000);
while(ele1 == ele2){
ele2 = Random.NextInt(10000);
}
this.ListOfLinks.Add(new Link(ListOfElements[ele1], ListOfElements[ele2]));
}
The code below will give a random array of the index to your list. So you can take randIndex[0] and randIndex[1] to get two random items.
Random rand = new Random();
List<string> myList = new List<string>() { "a","b","c"};
int[] randIndex = myList.Select((x,i) => new {i = i, rand = rand.Next()}).OrderBy(x => x.rand).Select(x => x.i).ToArray();
You need to find next element which is not used, also using .OrderBy(i => Guid.NewGuid())
to get random element
private Element GetNextAvaibaleElement() {
var usedElementIds = listOfLinks.Select(i => i.ElementOne).Union(listOfLinks.Select(i => i.ElementTwo));
return listOfElements.Where(i => !usedElementIds.Contains(i.Id)).OrderBy(i => Guid.NewGuid()).FirstOrDefault();
}
and then get two available elements
for (int i = 0; i < 5,000; i++)
{
this.ListOfLinks.Add(new Link(GetNextAvaibaleElement().Id,GetNextAvaibaleElement().Id));
}
See this dotnet fiddle here
Create an instance of the Random
class somewhere.
Eg
static Random rdm = new Random();
Then, use this rdm
instance to generate a random integer, delete that element from the list (so as not to reuse it), and keep going until you deplete your list.
List<Element> listOfElements; // list of 10k Elements
for (int i = 0; i < 5,000; i++)
{
int r = rdm.Next(listOfElements.Count);
Element elementOne = listOfElements[r];
listOfElements.RemoveAt(r);
r = rdm.Next(listOfElements.Count);
Element elementTwo = listOfElements[r];
this.ListOfLinks.Add(new Link(elementOne, elementTwo));
}
One approach to solving this is to create a list of integers representing the indexes into the ListOfElements
, then order that list in a random way. Then you can simply reference items in the ListOfElements
by index, sequentially walking through the randomized index list:
private static void Main()
{
for (int i = 0; i < 10000; i++) ListOfElements.Add(new Element());
// Create a randomly-ordered list of indexes to choose from
var rnd = new Random();
var randomIndexes = Enumerable.Range(0, ListOfElements.Count)
.OrderBy(i => rnd.NextDouble()).ToList();
// Now use our random indexes to pull unique items from the Element list
for (int i = 0; i < 10000; i += 2)
ListOfLinks.Add(new Link(ListOfElements[randomIndexes[i]].Id,
ListOfElements[randomIndexes[i + 1]].Id));
GetKeyFromUser("\nDone! Press any key to exit...");
}
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.