Although Loop with Destination in C # Linq

I would like to assign the variable vStreamID random number. This number must be re-generated, if my dictionary md_StreamDict contains generated number.

Long version:

 vStreamID = (new Random()).Next(1000, 9999).ToString(); while (md_StreamDict.ContainsKey(vStreamID)) { vStreamID = (new Random()).Next(1000, 9999).ToString(); } 

I would like to see something like LINQ

 md_StreamDict.ContainsKey(vStreamID) .while( x => x = (new Random()) .Next(1000, 9999) .ToString(); 

I know the example above is bananas. But I would be happy if there was a real way to achieve this. And no, we are not starting the usual discussion of readability again.;)

+4
source share
5 answers

If I understand you correctly, you just need a number in a known range, and this number should not already be in the dictionary, so do this without Random :

 Enumerable.Range(1000, 9999) .Where(n => !dict.ContainsKey(n)) .FirstOrDefault(); 
+4
source

You need a way to generate an infinite enumeration for stream random numbers. You can get closer with Enumerable.Range(0, int.MaxValue ):

 var rand = new Random(); var r = Enumerable.Range(0, int.MaxValue) .Select(s => rand.Next(1000, 9999)) .SkipWhile(s => md_StreamDict.ContainsKey(s.ToString())) .First(); 

Then r will contain the new key value not contained in the dictionary.

+4
source

Here are some bananas too:

You can create an IEnumerable that generates random numbers, for example:

 public class RandomList : IEnumerable<int> { public IEnumerator<int> GetEnumerator() { Random r = new Random(); while (true) yield return r.Next(1000, 9999); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return this.GetEnumerator(); } } 

Then you can do:

 // I guess one could implement a seed constructor, if one was so inclined RandomList rl = new RandomList(); int vStreamID = rl.SkipWhile(i => md_StreamDict.ContainsKey(i)).First(); 
+3
source

Now I have read your question 3 times, and I still don’t know why (or how) someone will do this using the LINQ expression. The only shorter solution that I see is what I wrote in the comment:

 var r = new Random(); do { vStreamID = r.Next(1000, 9999).ToString(); } while (md_StreamDict.ContainsKey(vStreamID)); 
+2
source

One approach would be to use yield to return values

  private static Random rand = new Random(); private static void Test() { Dictionary<string, string> values = new Dictionary<string, string>(); string vStreamId = GetNewValues().Where(x => !values.ContainsKey(x)).First(); } public static IEnumerable<string> GetNewValues() { While(true) { yield return rand.Next(1000, 9999).ToString(); } } 

Please note that if you create a new Random in each cycle, you will get the same value every time it is based on the system clock.

+2
source

All Articles