使用linq获取列表项中的日期差异

时间:2013-06-17 18:32:28

标签: c# .net linq

我有一份约会清单,我想在当前约会开始时间和最后约会结束时间之间做一些区别,以确保没有差别。如果有假的约会。

我目前的实施是......

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();
        }

有没有更好或更通用的方法来做到这一点?

根据要求...添加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;
        }

约会课没什么特别的。

/// <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; }

    }

1 个答案:

答案 0 :(得分:1)

在不知道如何实现this.Appointments属性或ToObservableCollection扩展方法的参数是什么的情况下,很难找到最有效的解决方案。但是,这样的事情应该有效:

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();
}