Skip to content

Instantly share code, notes, and snippets.

@blyry
Last active January 2, 2016 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save blyry/8342553 to your computer and use it in GitHub Desktop.
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.
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