C# Group Store Open Days by Like Times

Wednesday, July 9, 2014

I have a dictionary that stores each day of the week and the open/close times for that day.



Dictionary<string, string> hours = new Dictionary<string, string>();
hours.Add("M", String.Format("{0}-{1}", this.MondayOpen, this.MondayClosed));
hours.Add("T", String.Format("{0}-{1}", this.TuesdayOpen, this.TuesdayClosed));
hours.Add("W", String.Format("{0}-{1}", this.WednesdayOpen, this.WednesdayClosed));
hours.Add("Th", String.Format("{0}-{1}", this.ThursdayOpen, this.ThursdayClosed));
hours.Add("F", String.Format("{0}-{1}", this.FridayOpen, this.FridayClosed));
hours.Add("S", String.Format("{0}-{1}", this.SaturdayOpen, this.SaturdayClosed));
hours.Add("Su", String.Format("{0}-{1}", this.SundayOpen, this.SundayClosed));


I'd like to be able to iterate over the dictionary and group the days based on like times. For example, I'd like to display the data like this



M-Th 8:00 AM - 4:00 PM
F 8:00 AM - 6:00 PM
(leave Saturday and Sunday off if those days don't have open/close times)


I've tried a few different ways but haven't been able to get it completely right. Here's my most recent attempt.



private string FormatHours2()
{
StringBuilder sb = new StringBuilder();

// add all of the hours to a dictionary
Dictionary<string, string> hours = new Dictionary<string, string>();
hours.Add("M", String.Format("{0}-{1}", this.MondayOpen, this.MondayClosed));
hours.Add("T", String.Format("{0}-{1}", this.TuesdayOpen, this.TuesdayClosed));
hours.Add("W", String.Format("{0}-{1}", this.WednesdayOpen, this.WednesdayClosed));
hours.Add("Th", String.Format("{0}-{1}", this.ThursdayOpen, this.ThursdayClosed));
hours.Add("F", String.Format("{0}-{1}", this.FridayOpen, this.FridayClosed));
hours.Add("S", String.Format("{0}-{1}", this.SaturdayOpen, this.SaturdayClosed));
hours.Add("Su", String.Format("{0}-{1}", this.SundayOpen, this.SundayClosed));

// placeholder for the previous time range
string prevValue = String.Empty;

// inrun - indicates whether we are in a run of the same times.
// firstTime - indicates whether this is the first time through the loop.
bool inrun = false, firstTime = true;

for (int i = 0; i < hours.Count; i++)
{
KeyValuePair<string, string> entry = hours.ElementAt(i);

if (entry.Value != prevValue)
{
if (firstTime)
{
if (HasValue(entry.Value)) { sb.Append(entry.Key); }
}
else
{
if (!inrun)
{
if (HasValue(prevValue)) { sb.Append(String.Format(" {0},", hours.ElementAt(i - 1).Value)); }

if (HasValue(entry.Value)) { sb.Append(entry.Key); }
}
else
{
if (HasValue(prevValue))
{
sb.Append(String.Format("-{0} {1}", hours.ElementAt(i - 1).Key, hours.ElementAt(i - 1).Value));
}
if (HasValue(entry.Value)) { sb.Append(String.Format(",{0}", entry.Key)); }
}
}

inrun = false;
}
else
{
inrun = true;
}

firstTime = false;
prevValue = entry.Value;

// if we're on the last iteration, write the value
if (i == hours.Count() - 1)
{
if (inrun)
{
if (HasValue(entry.Value))
{
sb.Append(String.Format("-{0} {1}", entry.Key, entry.Value));
}
}
else
{
if (HasValue(prevValue))
{
sb.Append(String.Format(" {0}", hours.ElementAt(i - 1).Value));
}
}
}
}


return sb.ToString().TrimEnd(',');
}


This works pretty well with all scenarios except when days in the middle of the week are closed it doesn't put the comma.


Any help is greatly appreciated. If someone knows of a better way to do this, I'm open to suggestions. I don't even have to use a dictionary.


Thanks







http://ift.tt/1jqegiJ