2016-12-28 58 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