Since I like LINQ :)
Using my simplest implementation of the APL Scan operator for IEnumerable
(which is like Aggregate
but returns the intermediate results):
public static class IEnumerableExt {
// Explicit seed value
// TRes combineFn(TRes PrevResult, T CurValue)
public static IEnumerable<TRes> Scan<T, TRes>(this IEnumerable<T> src, TRes seed, Func<TRes, T, TRes> combineFn) {
foreach (var s in src) {
seed = combineFn(seed, s);
yield return seed;
}
}
}
And a simple class the increments each time it is read:
public class GeneratorInt {
int curValue = 1;
public int Value {
get {
return curValue++;
}
}
}
You can compute the answer (using null
for the empty boxes):
var ans = src.Scan(new {
EmpNumber = 0,
EmpName = "",
NumberOfDays = 0,
Days1 = (GeneratorInt)null,
Days2 = (GeneratorInt)null,
Days3 = (GeneratorInt)null,
Days4 = (GeneratorInt)null,
Days5 = (GeneratorInt)null
},
(acc, r) => new {
r.EmpNumber,
r.EmpName,
r.NumberOfDays,
Days1 = r.NumberOfDays >= 1 ? (acc.Days1 ?? new GeneratorInt()) : null,
Days2 = r.NumberOfDays >= 2 ? (acc.Days2 ?? new GeneratorInt()) : null,
Days3 = r.NumberOfDays >= 3 ? (acc.Days3 ?? new GeneratorInt()) : null,
Days4 = r.NumberOfDays >= 4 ? (acc.Days4 ?? new GeneratorInt()) : null,
Days5 = r.NumberOfDays >= 5 ? (acc.Days5 ?? new GeneratorInt()) : null,
}
)
.Select(a => new {
a.EmpNumber,
a.EmpName,
a.NumberOfDays,
Days1 = a.Days1?.Value,
Days2 = a.Days2?.Value,
Days3 = a.Days3?.Value,
Days4 = a.Days4?.Value,
Days5 = a.Days5?.Value,
})
.ToList();
If you need to handle differing potential number of Days
# fields, then you have to decide how you want to handle them - using one field of type List<int>
or of type IEnumerable<int>
, or using a DataTable
and create columns dynamically?