首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >排序字符串列表(保持者)

排序字符串列表(保持者)
EN

Stack Overflow用户
提问于 2015-01-14 11:59:17
回答 1查看 186关注 0票数 3

我有一个字符串列表(包含室友)如下:

代码语言:javascript
复制
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" },首先是所有没有后缀的软管,然后是后面有字母的,然后是所有其他的。因此,我将字符串拆分为前缀(实际数字)和后缀(数字本身后面的所有内容)。

代码语言:javascript
复制
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"开头?

如果有一个更优雅的方式来实现这一点,我将开放任何意见,以改进。

编辑:将输入分割成实际的数字和后缀主要是使用这个regex (\\d+)\\s*(\\S*)完成的。这将导致整数部分(实际的大小写)和字符串-在该数字之后的部分。之后,我们只通过使用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放在列表的末尾)。现在的结果也和预期的一样。因此,它似乎取决于列表中元素的初始顺序。很奇怪..。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-14 12:30:32

尝试如下,您没有给出如何分割前缀和后缀的示例,因此我编写了一个示例:

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27942444

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档