If you care to change your class a bit then follow this way!.
You can have 12 properties and map them into single int array. So you have int array of length 12. when intArray[0] = 1
means first month is available. if intArray[0] = 0
means first month is not available and so on.
You convert this int array into string with base-16 representation of 1-based index of each month, but if its not available then put 0 instead. Later we use a dictionary to get the name of months by giving its number instead.
Example 1:
"003456000a00"
This means months 3th,4th,5th,6th
and a = 10th
are available. then use regex to parse this and find the matches. The regex pattern would be [^0]+
. means it matches any character except 0
.
So the regex will give us this matches.
Match 1 : 3456
Match 2 : a
First match length is more than 1
means its a range of months. so we take the first character and last one. and we join them with -
. Here it will be 3
and 6
. So match 1 should become
Mar-Jun
Second match length is only 1
means its a single month. So it should become
Oct
Since we have two matches we join these with ,
and finally the out put is Mar-Jun , Oct
Example 2:
"020000000000"
Matches
Match 1 : 2
Since we have only 1 match and the match length is 1 this should become
Feb Only
Example 3:
"023456780000"
Matches
Match 1 : 234567
This is only one match but the length of this match is more than one. so we just take 2
and 7
and join them with -
.
Feb-Jul
Example 4:
"123456789abc"
Matches
Match 1 : 123456789abc
As you can see here we have all the months. the length of this match is 12 so it should be
Year round
Example 5:
"123456000abc"
Matches
Match 1 : 123456
Match 2 : abc
Here we have two matches. it can be Jan-Jun , Oct-Dec
but the better representation (as you mentioned in comment) is Oct-Jun
. That should be abc123456
. So we check if the last match ends with c
and first match starts with 1
then we join last match with first match.
Oct-Jun
Code:
It will become simple as you can see.
internal class AvailableYear
{
private readonly int[] _available;
private static readonly Regex MatchTrue = new Regex("[^0]+");
private static readonly Dictionary<string, string> GetName = new Dictionary<string, string>
{
{"1","Jan" },
{"2","Feb" },
{"3","Mar" },
{"4","Apr" },
{"5","May" },
{"6","Jun" },
{"7","Jul" },
{"8","Aug" },
{"9","Sep" },
{"a","Oct" },
{"b","Nov" },
{"c","Dec" },
};
public AvailableYear(params int[] available)
{
if (available.Length > 12) throw new IndexOutOfRangeException("given parameters should not exceed 12 months.");
_available = available;
}
public int AvaialableJan
{
get { return _available[0]; }
set { _available[0] = value; }
}
public int AvailableFeb
{
get { return _available[1]; }
set { _available[1] = value; }
}
public int AvailableMar
{
get { return _available[2]; }
set { _available[2] = value; }
}
public int AvailableApr
{
get { return _available[3]; }
set { _available[3] = value; }
}
public int AvaialableMay
{
get { return _available[4]; }
set { _available[4] = value; }
}
public int AvaialableJun
{
get { return _available[5]; }
set { _available[5] = value; }
}
public int AvaialableJul
{
get { return _available[6]; }
set { _available[6] = value; }
}
public int AvaialableAug
{
get { return _available[7]; }
set { _available[7] = value; }
}
public int AvaialableSep
{
get { return _available[8]; }
set { _available[8] = value; }
}
public int AvaialableOct
{
get { return _available[9]; }
set { _available[9] = value; }
}
public int AvaialableNov
{
get { return _available[10]; }
set { _available[10] = value; }
}
public int AvaialableDec
{
get { return _available[11]; }
set { _available[11] = value; }
}
public override string ToString()
{
string values = string.Join("", _available.Select((x, i) => x == 0 ? "0" : Convert.ToString(i + 1, 16)));
var matches = MatchTrue.Matches(values).Cast<Match>().Select(x => x.Value).ToList();
if (matches.Count == 0)
{
return "None";
}
if (matches[0].Length == 12)
{
return "Year round";
}
if (matches.Count == 1 && matches[0].Length == 1)
{
return GetName[matches[0]] + " Only";
}
else
{
if (matches.First().StartsWith("1") && matches.Last().EndsWith("c"))
{
matches[0] = matches.Last() + matches.First();
matches.RemoveAt(matches.Count - 1);
}
List<string> output = new List<string>();
foreach (var match in matches)
{
if (match.Length == 1)
{
output.Add(GetName[match]);
}
else
{
output.Add(GetName[match.First().ToString()] + "-" +
GetName[match.Last().ToString()]);
}
}
return string.Join(", ", output);
}
}
}
Here is the test.
static void Main()
{
AvailableYear ay = new AvailableYear(1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0);
Console.WriteLine(ay.ToString());
// Output : Jan , Apr-Jul , Nov
}
Update :
If you want to assign bool values in constructor you can change constructor to this.
public AvailableYear(params bool[] available)
{
if (available.Length > 12) throw new IndexOutOfRangeException("given parameters should not exceed 12 months.");
_available = available.Select(Convert.ToInt32).ToArray();
}
And the create the instance like this. without writing Convert.ToInt32 each time.
return new AvailableYear(AvailableJan, AvailableFeb, AvailableMar...., AvailableDec).ToString();