Last active
January 2, 2016 18:19
-
-
Save blyry/8342553 to your computer and use it in GitHub Desktop.
IComparer for our app - it compares shirt sizes, with overloads for a couple of DTOs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Text; | |
using System.Text.RegularExpressions; | |
using Cubrd.Services.DTOs; | |
namespace Cubrd.Services.Utility | |
{ | |
public class PropertySizeComparer : IComparer<ItemPropertyDTO>, IComparer<PropertyAllowedValueDTO>, IComparer<string> | |
{ | |
private static readonly Dictionary<string, int> EasySizes = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase) { { "s", 10 }, { "m", 11 }, { "l", 12 } }; | |
#region IComparer | |
public int Compare(ItemPropertyDTO x, ItemPropertyDTO y) | |
{ | |
return DoCompare(new SizeProperty(x.OptionValue, x.SortOrder), new SizeProperty(y.OptionValue, y.SortOrder)); | |
} | |
public int Compare(PropertyAllowedValueDTO x, PropertyAllowedValueDTO y) | |
{ | |
return DoCompare(new SizeProperty(x.Value, null), new SizeProperty(y.Value, null)); | |
} | |
public int Compare(string x, string y) | |
{ | |
return DoCompare(new SizeProperty(x, null), new SizeProperty(y, null)); | |
} | |
#endregion | |
#region private | |
private static int DoCompare(SizeProperty x, SizeProperty y) | |
{ | |
var firstPass = CompareSortOrder(x, y); | |
if (firstPass != null) | |
return firstPass.Value; | |
//if we made it here..parse | |
x.SortOrder = EasySizes.ContainsKey(x.OptionValue) ? EasySizes[x.OptionValue] : getSizeValue(x); | |
y.SortOrder = EasySizes.ContainsKey(y.OptionValue) ? EasySizes[y.OptionValue] : getSizeValue(y); | |
var newResult = CompareSortOrder(x, y); | |
if (newResult.HasValue) | |
return newResult.Value; | |
return 0; | |
} | |
private static int getSizeValue(SizeProperty x) | |
{ | |
int bonusNum = x.OptionValue.EndsWith("t", StringComparison.CurrentCultureIgnoreCase) ? 100 : 0; | |
var optionValue = x.OptionValue.ToLower().TrimEnd('t'); | |
//we need regexes for 4xt, 4t, and 4xlt => 4x,4 and 4xl; | |
//4T => 4 => 4X | |
if (Regex.IsMatch(optionValue, @"^\d+$")) | |
{ | |
//then it was in the form of 4t, most likely. | |
optionValue = optionValue + "x"; | |
} | |
//5XT -> 5X -> 5XL | |
if (Regex.IsMatch(optionValue, @"^\d+x$")) | |
optionValue = optionValue + "l"; | |
var match = Regex.Match(optionValue, @"^(\d+)x*([sl])"); | |
//the multiplier: 5x => exes = 5. XXXL => exes = 3 | |
int exes; | |
string theRest = ""; | |
if (match.Success) | |
{ | |
//will match 5l, 5s, 5xl, 5xxL, etc (because garbage data) | |
if (!int.TryParse(match.Groups[1].Value, out exes)) | |
exes = 0; | |
theRest = match.Groups[2].Value; | |
} | |
else | |
{ | |
//maybe it's just xxs or xxxl | |
exes = optionValue.TakeWhile(val => val == 'x').Count(); | |
//is it an extra large? | |
theRest = optionValue.Substring(exes); | |
} | |
int heuristic = 0; | |
if (theRest.Equals("s")) | |
heuristic = 10 - exes; | |
else if (theRest.Equals("l")) | |
heuristic = 12 + exes; | |
//bonusNum is for Ts: they need to sorted, but after the normal sizes. | |
int returnVal = heuristic + bonusNum; | |
return returnVal; | |
} | |
private static int? CompareSortOrder(SizeProperty x, SizeProperty y) | |
{ | |
if (x.SortOrder.HasValue && y.SortOrder.HasValue) | |
return x.SortOrder.Value == y.SortOrder.Value ? 0 : x.SortOrder.Value > y.SortOrder.Value ? 1 : -1; | |
if (x.SortOrder.HasValue && !y.SortOrder.HasValue) | |
return x.SortOrder.Value == 0 ? 0 : x.SortOrder.Value > 0 ? 1 : -1; | |
if (y.SortOrder.HasValue && !x.SortOrder.HasValue) | |
return y.SortOrder.Value == 0 ? 0 : y.SortOrder.Value > 0 ? 1 : -1; | |
return null; | |
} | |
#endregion | |
private class SizeProperty | |
{ | |
public string OptionValue { get; set; } | |
public decimal? SortOrder { get; set; } | |
public SizeProperty(string OptionValue, decimal? SortOrder) | |
{ | |
this.OptionValue = OptionValue; | |
this.SortOrder = SortOrder; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment