Reputation: 4822
I have a list of appointments, I would like to do a difference between the current appointment start time and last appointment end time to ensure there is no difference. If there is add a fake appointment.
My current implementation is...
public ObservableCollection<Appointment> FillGaps()
{
var appointments = this.Appointments.OrderByDescending(s => s.EndDate).ToList();
for (int i = 0; i < appointments.Count() - 1; i++)
{
var now = appointments[i];
var previous = appointments[i + 1];
if((now.StartDate.Value - previous.EndDate.Value).Days > 1)
{
// add a new appointment between this period
appointments.Add(new Appointment()
{
StartDate = previous.EndDate.Value.AddDays(1),
EndDate = now.StartDate.Value.AddDays(-1),
IsCurrent = false
});
}
}
return appointments.ToObservableCollection();
}
Is there a better or more generic way to do this?
As requested... Adding implementation of ToObservable...
/// <summary>
/// The to observable collection.
/// </summary>
/// <param name="coll">
/// The collection.
/// </param>
/// <typeparam name="T"> Object T
/// </typeparam>
/// <returns>
/// The <see cref="ObservableCollection"/>.
/// </returns>
public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> coll)
{
var c = new ObservableCollection<T>();
foreach (var e in coll)
{
c.Add(e);
}
return c;
}
Nothing special in Appointment class.
/// <summary>
/// The Appointment.
/// </summary>
[Serializable]
public class Appointment
{
public Appointment()
{
this.IsFake = false;
}
/// <summary>
/// Gets or sets the start date.
/// </summary>
public DateTime? StartDate { get; set; }
/// <summary>
/// Gets or sets the end date.
/// </summary>
public DateTime? EndDate { get; set; }
/// <summary>
/// Gets or sets the Is Fake
/// </summary>
public bool IsFake { get; set; }
}
Upvotes: 2
Views: 659
Reputation: 31208
Without knowing how the this.Appointments
property is implemented, or what the parameter to the ToObservableCollection
extension method is, it's difficult to come up with the most effective solution. However, something like this should work:
private static IEnumerable<Tuple<T, T>> ListPairs<T>(IEnumerable<T> source)
{
using (var enumerator = source.GetEnumerator())
{
if (!enumerator.MoveNext()) yield break;
T previous = enumerator.Current;
while (enumerator.MoveNext())
{
T current = enumerator.Current;
yield return new Tuple<T, T>(previous, current);
previous = current;
}
}
}
public ObservableCollection<Appointment> FillGaps()
{
var gaps = ListPairs(this.Appointments.OrderByDescending(s => s.EndDate))
.Where(pair => (pair.Item1.StartDate.Value - pair.Item2.EndDate.Value).Days > 1)
.Select(pair => new Appointment
{
StartDate = pair.Item2.EndDate.Value.AddDays(1),
EndDate = pair.Item1.StartDate.Value.AddDays(-1),
IsCurrent = false,
});
// NB: Assumes "this.Appointments" is a cheap call;
// Also assumes you don't need the results in any particular order.
return this.Appointments.Concat(gaps).ToObservableCollection();
}
Upvotes: 1