2012-07-27 55 views
1

有写这样的一个很好的方式:集类产品的查询等

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

PRODUCTOF(Range1, Range2).Sum((i,j) => i+17*j) 

其中PRODUCTOF是未知的东西给我。

当然,你可以绕过这个或为此编写一个函数,但也许有一个内置的语法,应该更喜欢。

+0

喜欢,笛卡尔产品? – Jodrell 2012-07-27 08:37:18

+0

是的,两个范围的笛卡尔乘积,以(i,j)或类似的数学方式进行索引。 – 2012-07-27 11:23:43

回答

1

如果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)); 
    } 
} 

,你可以使用像

Range1.CartesianProduct(Range2).Sum(p => p.item1+17*p.item2); 

,但是,我不知道你会获得那么多。正如你建议,你可以走了一步,

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)); 
    } 
} 

和使用这样,

Range1.CartesianProduct(Range2, (x, y) => x+17*y).Sum(); 

这确实看似整洁。


无论哪种方式,信贷去Jon Skeet提供我已穿好的窗口。

4

你的意思是这样的:

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来代替。

+0

这是我从来不知道的'SelectMany'的超载... – Rawling 2012-07-27 08:40:14

+0

谢谢;我希望更短,更容易阅读,因为我有很多复杂的公式,这些公式总结在两个范围内。我想我使用一个像DoubleSum(Range1,Range2,Func )的函数。 – 2012-07-27 09:12:44