2012-07-27 58 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