1

我发现了很多关于此的帖子,但未能将它们与我的情况相匹配。

我在列表中有一些字符串

List<string> list = new List<string>{ "100-1", "100-11", "100-3", "100-20" }

我使用以下代码对从该位置挑选的内容进行排序

void Main()
{
    string[] things= new string[] { "100-1", "100-11", "100-3", "100-20" };

    foreach (var thing in things.OrderBy(x => x, new SemiNumericComparer()))
    {    
        Console.WriteLine(thing);
    }
}

public class SemiNumericComparer: IComparer<string>
{
    public int Compare(string s1, string s2)
    {
        if (IsNumeric(s1) && IsNumeric(s2))
        {
            if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1;
            if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1;
            if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0;
        }

        if (IsNumeric(s1) && !IsNumeric(s2))
            return -1;

        if (!IsNumeric(s1) && IsNumeric(s2))
            return 1;

        return string.Compare(s1, s2, true);
    }

    public static bool IsNumeric(object value)
    {
        try {
            int i = Convert.ToInt32(value.ToString());
            return true; 
        }
        catch (FormatException) {
            return false;
        }
    }
}

我的输出是100-1, 100-11, 100-20, 100-3

我相信它正在接受-decimal比较这些值。其实我期待的结果是 100-1, 100-3, 100-11, 100-20。我只是想知道它实际上是在什么基础上进行排序的。任何帮助表示赞赏。100-2甚至我希望它能够以不同的方式对待100-20

就在飞行中,我在 Infragistic 控制网格中看到,在其中进行排序会产生与我在这里期望的结果相同的结果。

编辑

我在列表中有许多其他字符串值,有些是整数、双精度值等等。连字符只是这里提到的一个案例。

4

3 回答 3

4
var sorted = things.Select(s => s.Split('-'))
                .OrderBy(x => double.Parse(x[0]))
                .ThenBy(x => double.Parse(x[1]))
                .Select(x=>String.Join("-",x))
                .ToList();
于 2012-12-03T09:20:07.193 回答
2

这应该按预期工作:

string[] things= new string[] { "100-1", "100-11", "100-3", "100-20" };
IEnumerable<string> ordered = things
            .Select(s => new
            {
                str = s,
                firstPart = s.Split('-').ElementAtOrDefault(0),
                secondPart = s.Split('-').ElementAtOrDefault(1)
            })
            .OrderBy(x => int.Parse(x.firstPart))
            .ThenBy(x => int.Parse(x.firstPart))
            .Select(x => x.str);

foreach (string s in ordered)
    Console.WriteLine(s);

尽管它假定您的数据是严格的,否则您可以接受例外情况,fe at int.Parse(x.firstPart).

演示:http: //ideone.com/UJ5Yt4

于 2012-12-03T09:21:07.427 回答
1

如果要按第二个数字(连字符之后)对项目进行排序,则需要将字符串解析为数字,然后使用它进行排序。你可以试试:

string[] things = new string[] { "100-1", "100-11", "100-3", "100-20" };
var test = things.OrderBy(r => int.Parse(r.Split('-')[1])).ToArray();

您当前代码不起作用的原因可能是因为它无法将字符串解析为100-整数值并且您的函数IsNumeric返回 false。

于 2012-12-03T09:16:44.967 回答