C# 设置查询范围的类似乘积等

C# 设置查询范围的类似乘积等,c#,linq,C#,Linq,有没有一个很好的方法来写这样的东西: foreach ((i,j) in PRODUCTOF(Range1, Range2)) 或 我对PRODUCTOF一无所知 当然,您可以绕过这个问题或为此编写一个函数,但可能有一种内置语法更适合使用。您的意思是: foreach (var pair in Range1.SelectMany(x => Range2, (x, y) => new { x, y })) { // Use pair.x and pair.y } 或者对于您

有没有一个很好的方法来写这样的东西:

foreach ((i,j) in PRODUCTOF(Range1, Range2))

我对PRODUCTOF一无所知


当然,您可以绕过这个问题或为此编写一个函数,但可能有一种内置语法更适合使用。

您的意思是:

foreach (var pair in Range1.SelectMany(x => Range2, (x, y) => new { x, y }))
{
    // Use pair.x and pair.y
}
或者对于您的
Sum
示例:

var sum = Range1.SelectMany(x => Range2, (x, y) => new { x, y })
                .Sum(pair => pair.x + pair.y * 17);
作为查询表达式:

var query = from x in Range1
            from y in Range2
            select new { x, y };
var sum = query.Sum(pair => pair.x + pair.y * 17);

这是假设你想要交叉积-每一对都可能。如果您只想形成
{Range1(0)、Range2(0)}、{Range1(1)、Range2(1)}
等的对,那么您应该使用
Zip

您的意思是:

foreach (var pair in Range1.SelectMany(x => Range2, (x, y) => new { x, y }))
{
    // Use pair.x and pair.y
}
或者对于您的
Sum
示例:

var sum = Range1.SelectMany(x => Range2, (x, y) => new { x, y })
                .Sum(pair => pair.x + pair.y * 17);
作为查询表达式:

var query = from x in Range1
            from y in Range2
            select new { x, y };
var sum = query.Sum(pair => pair.x + pair.y * 17);

这是假设你想要交叉积-每一对都可能。如果您只是试图形成
{Range1(0)、Range2(0)}、{Range1(1)、Range2(1)}
等的对,那么您应该使用
Zip
来代替。

如果
SelectMany
太冗长,我想您可以编写一个扩展,比如

public static class Extensions
{
    public static IEnumerable<Tuple<T,T>> CartesianProduct<T>(
            this IEnumerable<T> source,
            IEnumerable<T> multiplier)
    {
        return source.SelectMany(s => multiplier, (s, m) => Tuple.Create(s, m));   
    }
}
但是,我不确定你会得到那么多。正如你所建议的,你可以更进一步

public static class Extensions
{
    public static IEnumerable<TResult> CartesianProduct<T, TResult>(
            this IEnumerable<T> source,
            IEnumerable<T> multiplier,
            Func<T, T, TResult> combiner)
    {
        return source.SelectMany(s => multiplier, (s, m) => combiner(s, m));   
    }
}
看起来确实有点整洁



不管是哪种方式,都要归功于提供了我穿好衣服的窗口。

如果
SelectMany
太冗长,我想你可以编写一个扩展,比如

public static class Extensions
{
    public static IEnumerable<Tuple<T,T>> CartesianProduct<T>(
            this IEnumerable<T> source,
            IEnumerable<T> multiplier)
    {
        return source.SelectMany(s => multiplier, (s, m) => Tuple.Create(s, m));   
    }
}
但是,我不确定你会得到那么多。正如你所建议的,你可以更进一步

public static class Extensions
{
    public static IEnumerable<TResult> CartesianProduct<T, TResult>(
            this IEnumerable<T> source,
            IEnumerable<T> multiplier,
            Func<T, T, TResult> combiner)
    {
        return source.SelectMany(s => multiplier, (s, m) => combiner(s, m));   
    }
}
看起来确实有点整洁



无论哪种方式,这都归功于提供了我穿好衣服的窗户。

谢谢;我希望能有一些简短易读的东西,因为我有很多复杂的公式,它们在两个范围内求和。我想我使用了一个像DoubleSum(Range1,Range2,Func)这样的函数;我希望能有一些简短易读的东西,因为我有很多复杂的公式,它们在两个范围内求和。我想我使用了一个像DoubleSum(Range1,Range2,Func)这样的函数。是的,两个范围的笛卡尔积,以数学方式被索引为(I,j)或类似的东西。是的,两个范围的笛卡尔积,以数学方式被索引为(I,j)或类似的东西。