このようなものを書くための良い方法はありますか?
foreach ((i,j) in PRODUCTOF(Range1, Range2))
また
PRODUCTOF(Range1, Range2).Sum((i,j) => i+17*j)
ここで、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) }
etcのペアを形成しようとしているだけの場合は、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));
}
}
あなたが好きなように使うことができます
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();
ややきれいに見えます。
いずれにせよ、クレジットは私が着飾った窓を提供してくれたJonSkeetに与えられます。