我想为变量vStreamID
分配一个随机数。只要我的字典md_StreamDict
包含生成的数字,就应该新生成此数字。
长版:
vStreamID = (new Random()).Next(1000, 9999).ToString();
while (md_StreamDict.ContainsKey(vStreamID)) {
vStreamID = (new Random()).Next(1000, 9999).ToString();
}
我想看看LINQ风格的东西
md_StreamDict.ContainsKey(vStreamID)
.while( x => x = (new Random())
.Next(1000, 9999)
.ToString();
我知道上面的例子是香蕉。但是如果真的有办法实现这一点,我会很高兴。不,我们还没有开始关于可读性的通常讨论。 ;)
答案 0 :(得分:4)
您需要一种为流式随机数生成无限可枚举的方法。您可以使用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();
然后r
将包含未包含在字典中的新键值。
答案 1 :(得分:4)
如果我理解你的权利你只需要一个众所周知的范围内的数字,这个数字不应该已经在字典中,所以不用Random
这样做:
Enumerable.Range(1000, 9999)
.Where(n => !dict.ContainsKey(n))
.FirstOrDefault();
答案 2 :(得分:3)
这也是一些香蕉:
您可以创建一个可生成随机数的IEnumerable,例如:
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();
}
}
然后你可以这样做:
// 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 :(得分:2)
现在我已经读过你的问题3次了,我仍然不知道为什么(或怎么样)任何人都会用LINQ表达式来做这件事。我看到的唯一更简短的解决方案是我在评论中写的:
var r = new Random();
do {
vStreamID = r.Next(1000, 9999).ToString();
} while (md_StreamDict.ContainsKey(vStreamID));
答案 4 :(得分:2)
一种方法是使用yield来返回值
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();
}
}
请注意,如果在每个循环上生成一个新的Random,则每次都会获得与基于系统时钟相同的值。