而循环与C#Linq中的赋值

时间:2012-12-28 13:39:23

标签: c# linq loops syntax random

我想为变量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();

我知道上面的例子是香蕉。但是如果真的有办法实现这一点,我会很高兴。不,我们还没有开始关于可读性的通常讨论。 ;)

5 个答案:

答案 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,则每次都会获得与基于系统时钟相同的值。