C# C Linq中带赋值的While循环
我想给变量vStreamID分配一个随机数。只要my dictionary md_StreamDict包含生成的号码,就应该新生成该号码 长版本:C# C Linq中带赋值的While循环,c#,linq,loops,syntax,random,C#,Linq,Loops,Syntax,Random,我想给变量vStreamID分配一个随机数。只要my dictionary md_StreamDict包含生成的号码,就应该新生成该号码 长版本: vStreamID = (new Random()).Next(1000, 9999).ToString(); while (md_StreamDict.ContainsKey(vStreamID)) { vStreamID = (new Random()).Next(1000, 9999).ToString(); } 我想看看LINQ风格
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();
我知道上面的例子是香蕉。但如果有一个真正的方法来实现这一点,我会很高兴。不,我们不会再开始关于可读性的讨论了 现在我已经读了你的问题三遍了,我仍然不知道为什么或者怎么会有人用LINQ表达式来做这件事。我看到的唯一简短的解决方案是我在评论中写的:
var r = new Random();
do {
vStreamID = r.Next(1000, 9999).ToString();
} while (md_StreamDict.ContainsKey(vStreamID));
您需要一种方法来生成流式随机数的无限枚举。您可以使用Enumerable.Range0、int.MaxValue进行近似计算:
那么r将包含字典中未包含的新键值。如果我理解正确,您只需要一个已知范围内的数字,而这个数字不应该已经存在于字典中,因此请不要随机:
这里还有一些香蕉: 您可以创建生成随机数的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();
}
}
一种方法是使用收益率返回值
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();
}
}
请注意,如果在每个循环上生成一个新的随机数,则每次都会得到基于系统时钟的相同值。如果使用do{}while;,即使是长版本也可能更短:-所以你只需要一个明确的数字,这个数字不应该已经在字典里了,为什么你需要随机的呢?我认为神经缺陷需要在他的字典里有一个新的条目,其中键是随机的,字典里不存在。为什么是linq,dunno.永远不要给新Random打那么多次电话。只需创建一个Random实例,然后重用该随机数生成器。否则,您可能会创建相同的随机实例—时间可能不会从一个实例更改到下一个实例,然后。下一个。。。将为每个随机实例提供相同的数字。如果希望9999成为可能的结果,请改用.Next1000、10000。这将生成一个值。我不确定您是否理解Jon,GetNewValues函数在每次调用时都返回一个新值,LINQ语句将选择字典中不存在的第一个值。请尝试运行它。获取新值将生成一个随机数,然后返回。你必须做真正的收益回报…这不会创建一个无限的列表,你不能100%确定它将包含1000-9999之间的所有值。你要么在真正产生random.Next的时候做,要么在该范围内创建int列表并洗牌。@JonB:没错。虽然我认为如果你一路走到4294967296却没有找到丢失的钥匙,你可以写一本关于统计异常的书。如果你的字典已经满了,你需要等待很长时间才能用任何方法找到一个漏洞。不要在循环中创建一个随机的实例!见@OlivierJacot Descombes:好的观点。更新。我只是盲目地用LINQ格式复制OP的原始逻辑。@Neurodefekt这总是给出dict中没有的最低四位数或小于10999的数字。你甚至可以说。FirstOrDefaultn=>!迪克特·康纳斯基。在任何情况下,如果dict包含1000和10998之间的所有键,则返回0。哎呀,你知道Range10009999给出的数字是1000到10998吗?@sll:让我更明确一点:new Random.next10009999对应的范围是Enumerable.Range10008999,所以你的答案错了。如果原来的海报真的是指新的Random.next100010000,那就是Enumerable.range10009000。
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();
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();
}
}