2016-12-28 55 views
1

問候請記住,沒有數據庫,這些都是假的功能,使測試組件的工作,我有一個列表,這使得一個24 hours基於15 minutes規模,並從這種方法產生:如何從循環內的列表中刪除範圍?

public List<ScaleLine> GetHoursAndScales(ScaleLine.Scales scale = ScaleLine.Scales.Fiftheen) 
    { 
     int _scale = Convert.ToInt32(scale); 
     int _count = _scale * 24; 
     int _scaleCount = 60/_scale; 

     List<ScaleLine> _list = new List<ScaleLine>(); 

     var start = DateTime.Today; 
     var clockQuery = from offset in Enumerable.Range(1, _count) 
         select TimeSpan.FromMinutes(_scaleCount * offset); 
     foreach (var time in clockQuery) 
     { 
      _list.Add(new ScaleLine() { Id = _list.Count, Hours = (start + time).ToString("HH:mm"), Scale = _scale }); 
     } 
     return _list; 
    } 

而且我有被稱爲保留小時,這是產生這種方法的另一個列表:

public List<Reservedhours> AllReservedHours() 
    { 
     return new List<Reservedhours> 
     { 
      new Reservedhours() { Id = 1, Date = DateTime.Now, StartPoint = "08:00", EndPoint = "10:00" }, 
      new Reservedhours() { Id = 2, Date = DateTime.Now, StartPoint = "14:00", EndPoint = "16:00" }, 
      new Reservedhours() { Id = 3, Date = DateTime.Now, StartPoint = "20:00", EndPoint = "22:00" }, 
      new Reservedhours() { Id = 4, Date = DateTime.Now.AddDays(1), StartPoint = "07:00", EndPoint = "11:00" }, 
      new Reservedhours() { Id = 5, Date = DateTime.Now.AddDays(1), StartPoint = "13:00", EndPoint = "15:00" }, 
      new Reservedhours() { Id = 6, Date = DateTime.Now.AddDays(1), StartPoint = "15:00", EndPoint = "18:00" }, 
      new Reservedhours() { Id = 7, Date = DateTime.Now.AddDays(1), StartPoint = "18:00", EndPoint = "22:00" }, 

     }; 
    } 

現在我有,基於保留時間和第一列表產生24小時產生可用時段另一個列表:

public List<ScaleLine> GetAvailableHours(DateTime date, ScaleLine.Scales scale = ScaleLine.Scales.Fiftheen) 
    { 
     List<Reservedhours> _timeLine = AllReservedHours().Where(x => x.Date.Date == date.Date) 
      .Select(a => new Reservedhours {StartPoint = a.StartPoint, EndPoint = a.EndPoint }) 
      .ToList(); 
     List<ScaleLine> _available = GetHoursAndScales(); 

     //scale convert: 
     int _scale = Convert.ToInt32(scale); 

     foreach (var _item in _timeLine) 
     { 
      int index = _available.Where(x => x.Hours == _item.StartPoint) 
       .SingleOrDefault().Id; 

      //Convert to datetime 
      DateTime _opening = DateTime.ParseExact(_item.StartPoint, "HH:mm", System.Globalization.CultureInfo.InvariantCulture); 
      DateTime _closing = DateTime.ParseExact(_item.EndPoint, "HH:mm", System.Globalization.CultureInfo.InvariantCulture); 
      //Getting duration time 
      TimeSpan duration = _closing.Subtract(_opening); 
      double _duration = duration.TotalMinutes; 
      //getting coverage 
      int timeScale = 60/_scale; 
      int coverage = Convert.ToInt32(_duration)/timeScale; 

      //remove unavailable timespots 
      _available.RemoveRange(index, coverage); 
     } 
     return _available; 
    } 

但問題是當Foreach循環開始將刪除第一個範圍的基礎上正確的指數,可以說如果_available列表中有96成員它消除了他們的8,所以第二次它應該有88成員,並找到index在那些88成員中,但它並沒有得到索引錯誤(它將索引視爲該列表仍然有96成員),因此循環中的每個其他操作都是如此。我該如何解決這個問題?有沒有一種方法,我可以得到可用的列表而不做foreach循環?

+0

從數組中刪除項目時,刪除中間的項目會影響刪除項目後所有項目的索引。解決的辦法是從列表的末尾開始,像這樣往前移動:for(int i = _timeLine.Count() - 1; i> = 0; i - ){var _item = _timeLine [i];} – jdweng

回答

1

問題是您對索引的確定。而問列表所需對象的索引,你問一個對象的屬性值,並以此作爲指標:

int index = _available.Where(x => x.Hours == _item.StartPoint) 
         .SingleOrDefault() 
         .Id; 

要麼你問真該指數通過調用IndexOf()

var matchingItem = _available.Where(x => x.Hours == _item.StartPoint) 
          .First(); 
var index = _available.IndexOf(matchingItem); 

或者你用別的東西代替你的.RemoveRange(),這真的會消除你想要的元素。

+0

呃,你是對的! – Valkyrie

+0

@Valkyriee:作爲一個方面說明:如果在使用之前沒有檢查無效性(如'.SingleOrDefault().Id'),那麼使用'OrDefault()'是沒有意義的。另外一定要理解'.First()'和'.Single()'之間的區別。 – Oliver

+0

Surething =)謝謝! – Valkyrie