关于c#:是否有类似`continue`的东西绕过或跳过LINQ中的查询迭代?

Is there something like `continue` to bypass or skip an iteration of query in LINQ?

拿这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        int[] queryValues1 = new int[10] {0,1,2,3,4,5,6,7,8,9};
        int[] queryValues2 = new int[100]; // this is 0 to 100

        for (int i = 0; i < queryValues2.Length; i++)
        {
            queryValues2[i] = i;
        }

        var queryResult =
            from qRes1 in queryValues1
            from qRes2 in queryValues2
            where qRes1 * qRes2 == 12
            select new { qRes1, qRes2 };

        foreach (var result in queryResult)
        {
            textBox1.Text += result.qRes1 +" *" + result.qRes2 +" = 12" + Environment.NewLine;
        }

显然,这将导致在代码:

1
2
3
4
5
1 * 12 = 12
2 * 6 = 12
3 * 4 = 12
4 * 3 = 12
6 * 2 = 12

但我需要的是一个只有3线。我不想要的,如果是2×6=12查询.如果是6×2,12。该过滤器有一路或在LINQ查询中,我已经做afterward循环?

我的问题,只是给我一个样本的均值。所以我想知道,在这样的方式做的事物是什么的类型的对象被linqed到!


一般来说,简单的解决方案更多的是Where条件,因为Where子句是定义上的内容,这会导致Linq跳过迭代:

1
2
3
4
5
6
var queryResult =
    from qRes1 in queryValues1
    from qRes2 in queryValues1
    where qRes1 * qRes2 == 12
    && qRes1 <= Math.Sqrt(12)
    select new { qRes1, qRes2 };


可以使用.distinct()并创建自己的IEqualityComparer,根据"equals"在本例中的含义对对象进行比较。

因此,对于您的原始示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
class PairSetEqualityComparer : IEqualityComparer<Tuple<int, int>>
    {
        public bool Equals(Tuple<int, int> x, Tuple<int, int> y)
        {
            return (x.Item1 == y.Item1 && x.Item2 == y.Item2) ||
                   (x.Item1 == y.Item2 && x.Item2 == y.Item1);
        }

        public int GetHashCode(Tuple<int, int> obj)
        {
            return obj.Item1*obj.Item2;
        }
    }

你可以这样使用它:

1
2
3
4
5
var queryResult =
            (from qRes1 in queryValues1
            from qRes2 in queryValues2
            where qRes1 * qRes2 == 12
            select new Tuple<int, int>(qRes1, qRes2)).Distinct(new PairSetEqualityComparer());


takewhile(condition):从序列返回元素,只要指定的条件为true,然后跳过其余元素。

1
foreach (var result in queryResult.TakeWhile(x => x.qRes1 <= Math.Sqrt(12)))