Reputation: 3228
Greetings Please keep in mind there is no database and these are fake functions to make the component work for testing, i have a List which makes a 24 hours
based on 15 minutes
scale and produces from this method:
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;
}
And i have another list which is called Reserved hours which is produces on this method:
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" },
};
}
Now i have another list that produces the available hours based on reserved hours and first list that produces 24 hours:
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;
}
But problem is when the Foreach
loop starts it removes the first range correctly based on its index, lets say if _available
list has 96
members it removes 8
of them, so second time it should have 88
members and find the index
within those 88
members but it doesn't and gets the index wrong (it takes the index as if the list still had 96
members) and so goes for every other action within the loop. how can i fix this issue? is there a way i can get the available list without doing a foreach loop?
Upvotes: 1
Views: 90
Reputation: 45101
The problem is your determination of the index. Instead of asking the list for the index of the desired object, you ask for the property value of an object and using this as index:
int index = _available.Where(x => x.Hours == _item.StartPoint)
.SingleOrDefault()
.Id;
Either you ask really for the index by calling IndexOf()
:
var matchingItem = _available.Where(x => x.Hours == _item.StartPoint)
.First();
var index = _available.IndexOf(matchingItem);
Or you replace your .RemoveRange()
by something else, that really removes your desired elements.
Upvotes: 1