2015-01-14 47 views
3

我有一个字符串(含housenumbers)如下列表:排序的字符串(housenumbers)列表

List<string> myList = new List<string> { "11", "11a", "11 a", "11-1", "11a-1" }; 
myList.Sort(new MyComparer()); 

现在我要被归类为{ "11", "11a", "11 a", "11a-1", "11-1" }列表意思:第一,没有后缀的所有hosenumbers ,那些有一封信的人,然后是其他人。所以我把我的字符串分成前缀(实际数字)和后缀(数字本身后面的所有内容)。

private class MyComparer : IComparer<string> 
{ 

    protected virtual int compareHouseNumbers(string hnr1, string hnr2) 
    { 
     // ... 
     // split number and suffix 
     // ... 

     // housenumbers (integers) are also equal so let the suffix decide which one is greater 
     // the suffixes do not contain any spaces now 
     if (String.IsNullOrEmpty(suffix1)) return -1; 
     else if (String.IsNullOrEmpty(suffix2)) return 1; 

     // the following shell ensure that a letter comes "before" any other special char (such as "-" or "/") 
     if (Char.IsLetter(suffix1.FirstOrDefault()) && !Char.IsLetter(suffix2.FirstOrDefault())) return -1; 
     else if (!Char.IsLetter(suffix1.FirstOrDefault()) && Char.IsLetter(suffix2.FirstOrDefault())) return 1; 
     // if we have more complexity (compare 11a-1 with 11a-2) we use standard string-comparison 
     return String.Compare(suffix1, suffix2); 
    } 

    /// <inheritDoc/> 
    public int Compare(string lbz1, string lbz2) 
    { 
     return this.compareHouseNumbers(lbz1, lbz2); 
    } 
} 

但我有基于这些后缀排序列表的问题。我得到的列表是{"11", "11 a", "11a", "11-1", "11a-1"}尽管互换条目"11a""11 a"适合我们的用途,但我不明白为什么最后一项是"11a-1"而不是"11-1"。我已经通过比较进行了调试,但显然这两个成员从来没有直接比较过,因此很难理解这里发生的事情。我可以做些什么来获得以"a"开头的后缀?

如果可能有一个更优雅的方式来实现这一点,我打开任何意见,以改善。

编辑:将输入分割成实际的数字和后缀主要是使用这个正则表达式(\\d+)\\s*(\\S*)。这将导致整数部分(实际的housnumber)和该数字后面的字符串部分。之后,我们仅通过使用suffix1 = suffix1.Trim(' ', '-', '/');suffix2适当地)修饰任何非字母数字字符。尽管如此,我们并没有实际比较-1a-1,但是1a-1。然而,这并不会改变结果本身的任何内容(因为-11都比在a中小)。

EDIT2:我消除了一些成员的名单之内,这样只有两个有问题的有剩余:List<string> myList = new List<string> { "11-1", "11a-1" };已经改变了这种排序的结果是如预期:{ "11a-1", "11-1" }

EDIT3:我只是改变了顺序列表中的成员(将11放在列表的末尾)。现在结果也如预期。所以它似乎取决于列表中元素的初始顺序。很奇怪...

+3

“11A-1”,是进一步下降,从而比“11-1”,因为“ - ”的char值比“a”低。看看ASCII表格。您可能需要以某种方式定义您的自定义字符顺序。 –

+0

当你比较sufixes“”-1“”和“”a-1“”时,''-1''首先变小,因为减号的ASCII码小于“a”的代码,所以它是smalelr。 – CiaPan

+0

这就是为什么我介绍了这个中间步骤,我检查第一个字母是否是一个字母......因此'11-1'会对'11a-1'失去,不是吗? – HimBromBeere

回答

0

尝试以下,你没有给你如何分割的前缀和后缀所以我做了一个了一个例子:

private class MyComparer : IComparer<string> 
{ 

    private static readonly Regex matchRegex = new Regex(@"^(?<prefix>\d+)(?<spaces>\s*)(?<suffix>.*?)$"); 


    private int match(string compare, out string prefix, out string suffix) { 
     var match= matchRegex.Match(compare); 
     prefix=match.Groups["prefix"].Value; 
     suffix=match.Groups["suffix"].Value; 
     return match.Groups["spaces"].Value.Length; 
    } 
    protected virtual int compareHouseNumbers(string hnr1, string hnr2) 
    { 
     // ... 
     // split number and suffix 
     // ... 
     string prefix1; 
     string prefix2; 
     string suffix1; 
     string suffix2; 
     var spaces1 = match(hnr1, out prefix1,out suffix1); 
     var spaces2 = match(hnr2, out prefix2,out suffix2); 

     Debug.WriteLine("Comparing '{0}' and '{1}'",suffix1,suffix2); 
     var prefixCompare = String.Compare(prefix1,prefix2); 
     if (prefixCompare != 0) { 
      return prefixCompare; 
     } 
     // housenumbers (integers) are also equal so let the suffix decide which one is greater 
     // the suffixes do not contain any spaces now 

     // FIX IS HERE!!! 
     // Previous code would compare "11" and "11" and return -1 which confuses the sort 
     if (String.IsNullOrEmpty(suffix1)) return (String.IsNullOrEmpty(suffix2)) ? 0 : -1; 
     else if (String.IsNullOrEmpty(suffix2)) return 1; 

     // the following shell ensure that a letter comes "before" any other special char (such as "-" or "/") 
     if (Char.IsLetter(suffix1.FirstOrDefault()) && !Char.IsLetter(suffix2.FirstOrDefault())) return -1; 
     else if (!Char.IsLetter(suffix1.FirstOrDefault()) && Char.IsLetter(suffix2.FirstOrDefault())) return 1; 
     // if we have more complexity (compare 11a-1 with 11a-2) we use standard string-comparison 
     var result = String.Compare(suffix1, suffix2); 

     // if the suffixes are equal sort on the number of spaces between prefix and suffix 
     if (result == 0) { 
      return (spaces1 - spaces2) <0 ? -1 : (spaces1 == spaces2) ? 0: 1; 
     } 
     return result; 
    } 

    /// <inheritDoc/> 
    public int Compare(string lbz1, string lbz2) 
    { 
     return this.compareHouseNumbers(lbz1, lbz2); 
    } 
} 
+0

请注意这里没有空的检查,你可能想要添加 –

+0

虽然你很好地猜测了分割你的解决方案的代码似乎没有给我的文章添加任何东西(除了最后一次检查结果)。 – HimBromBeere

+0

@HimBromBeere你说得对,我是白痴,我想念我的测试结果,让我修复它 –