Last active
November 29, 2018 15:32
-
-
Save trienow/2e14467dffb00479329220d709c2db87 to your computer and use it in GitHub Desktop.
Compares adjacent numerals as numbers and the rest as normal text. Probably not efficient, but it works fine.
This file contains hidden or 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; | |
| using System.Text.RegularExpressions; | |
| using System.Windows.Forms; | |
| public class ListViewSorter : IComparer | |
| { | |
| const string HUMAN_COMPARE = "(?'str'[^0-9]+)|(?'num'[0-9]+)"; | |
| public int Column { get; set; } = 0; | |
| public int Direction { get; set; } = 1; | |
| public int Compare(object x, object y) | |
| { | |
| int result = 0; | |
| ListViewItem lvi1 = x as ListViewItem; | |
| ListViewItem lvi2 = y as ListViewItem; | |
| string t1 = lvi1.SubItems[Column].Text; | |
| string t2 = lvi2.SubItems[Column].Text; | |
| int result = 0; | |
| if (t1 != t2) | |
| { | |
| MatchCollection m1 = Regex.Matches(t1, HUMAN_COMPARE, RegexOptions.ExplicitCapture); | |
| MatchCollection m2 = Regex.Matches(t2, HUMAN_COMPARE, RegexOptions.ExplicitCapture); | |
| int shortest = Math.Min(m1.Count, m2.Count); | |
| for (int i = 0; i < shortest; i++) | |
| { | |
| string text1 = m1[i].Groups[1].Value; | |
| string text2 = m2[i].Groups[1].Value; | |
| bool numberIn1 = text1 == string.Empty; | |
| bool numberIn2 = text2 == string.Empty; | |
| if (numberIn1) | |
| { | |
| if (numberIn2) | |
| { | |
| //Number comparison if both parts are numbers | |
| int i1 = int.Parse(m1[i].Groups[2].Value); | |
| int i2 = int.Parse(m2[i].Groups[2].Value); | |
| if (i1 < i2) | |
| { | |
| result = -1; | |
| } | |
| else if (i1 > i2) | |
| { | |
| result = 1; | |
| } | |
| } | |
| else | |
| { | |
| //Part 1 is a number, but part 2 is text | |
| result = -1; | |
| } | |
| } | |
| else if (numberIn2) | |
| { | |
| //Part 1 is text, but part 2 is a number | |
| result = 1; | |
| } | |
| else | |
| { | |
| //String comparison if both parts are strings | |
| result = string.Compare(text1, text2, StringComparison.InvariantCulture); | |
| } | |
| if (result != 0) | |
| { | |
| break; | |
| } | |
| } | |
| } | |
| return Direction * result; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment