このような for ループよりも、一度に 5 つのアイテムを実装するよりエレガントな方法はありますか?
var q = Campaign_stats.OrderByDescending(c=>c.Leads).Select(c=>c.PID).Take(23);
var count = q.Count();
for (int i = 0; i < (count/5)+1; i++)
{
q.Skip(i*5).Take(5).Dump();
}
for(int i = 0; i <= count; i+=5)
{
}
したがってDump()
、の5つのアイテムごとに効率的に呼び出す必要がありますq
。
あなたが今持っている解決策は、ループIEnumerable<T>
を通して毎回繰り返されます。for
次のようなことを行う方が効率的かもしれません:(あなたのタイプが何であるかわからないので、私は使用していますT
)
const int N = 5;
T[] ar = new T[N]; // Temporary array of N items.
int i=0;
foreach(var item in q) { // Just one iterator.
ar[i++] = item; // Store a reference to this item.
if (i == N) { // When we have N items,
ar.Dump(); // dump them,
i = 0; // and reset the array index.
}
}
// Dump the remaining items
if (i > 0) {
ar.Take(i).Dump();
}
これは1つのイテレータのみを使用します。変数の名前がq
であると考えると、これは「クエリ」の略であると想定しています。これは、これがデータベースに対するものであることを意味します。したがって、イテレータを1つだけ使用すると、非常に有益な場合があります。
このコードを保持し、拡張メソッドでラップする場合があります。「塊」はどうですか?
public static IEnumerable<IEnumerable<T>> Clump<T>(this IEnumerable<T> items, int clumpSize) {
T[] ar = new T[clumpSize];
int i=0;
foreach(var item in items) {
ar[i++] = item;
if (i == clumpSize) {
yield return ar;
i = 0;
}
}
if (i > 0)
yield return ar.Take(i);
}
コードのコンテキストでそれを呼び出す:
foreach (var clump in q.Clump(5)) {
clump.Dump();
}
代わりに 5 で反復してみてください!
for(int i = 0; i < count; i += 5)
{
//etc
}
GroupBy と Zip を使用して LINQ を追加します。
q
// add indexes
.Zip(Enumerable.Range(0, Int32.MaxValue),(a,index)=> new {Index=index, Value=a})
.GroupBy(m=>m.Index /5) // divide in groups by 5 items each
.Select(k => {
k.Select(v => v.Value).Dump(); // Perform operation on 5 elements
return k.Key; // return something to satisfy Select.
});