如何对C#中混合整数的字符串列表进行排序?

如何对C#中混合整数的字符串列表进行排序?,c#,algorithm,sorting,C#,Algorithm,Sorting,我有以下清单: 一, 2. 3. 10 20 30 狗 猫 30只狗 30猫 我希望对其进行排序,以便得到以下列表: 12302030猫狗猫狗 我怎样才能在C#中做到这一点?我基本上想按照以下规则对列表进行排序: 整数按升序排序。以整数开头的任何值都将基于该整数值进行排序。任何不以整数开头的值都将按其字符串值排序。听起来好像您想要实现一个自定义比较器,然后将该自定义比较器传递给排序方法 戴夫·比什的例子很好;但如果你不想使用正则表达式,这里有一个我编写的过程版本 static void

我有以下清单:

一, 2. 3. 10 20 30 狗 猫 30只狗 30猫

我希望对其进行排序,以便得到以下列表:

12302030猫狗猫狗

我怎样才能在C#中做到这一点?我基本上想按照以下规则对列表进行排序:


整数按升序排序。以整数开头的任何值都将基于该整数值进行排序。任何不以整数开头的值都将按其字符串值排序。

听起来好像您想要实现一个自定义比较器,然后将该自定义比较器传递给排序方法

戴夫·比什的例子很好;但如果你不想使用正则表达式,这里有一个我编写的过程版本

    static void Main(string[] args)
    {
        IEnumerable<string> strings = new[] { "1", "2", "3", "10", "20", "30", "Dog", "Cat", "30Dog", "30Cat" };
        strings = strings.OrderBy(s => s, new CustomComparer());
        var joined = string.Join(" ", strings);
        Console.WriteLine(joined);
        Console.ReadLine();
    }

    public class CustomComparer : IComparer<string>
    {
        public int Compare(string s1, string s2)
        {
            int x, y;
            bool xInt, yInt;
            xInt = int.TryParse(s1, out x);
            yInt = int.TryParse(s2, out y);
            if (xInt && yInt)
                return x.CompareTo(y);
            if (xInt && !yInt)
            {
                if (this.SplitInt(s2, out y, out s2))
                {
                    return x.CompareTo(y);
                }
                else
                {
                    return -1;
                }
            }
            if (!xInt && yInt)
            {
                if (this.SplitInt(s1, out x, out s1))
                {
                    return y.CompareTo(x);
                }
                else
                {
                    return 1;
                }
            }

            return s1.CompareTo(s2);
        }

        private bool SplitInt(string sin, out int x, out string sout)
        {
            x = 0;
            sout = null;
            int i = -1;                
            bool isNumeric = false;
            var numbers = Enumerable.Range(0, 10).Select(it => it.ToString());
            var ie = sin.GetEnumerator();
            while (ie.MoveNext() && numbers.Contains(ie.Current.ToString()))
            {
                isNumeric |= true;
                ++i;
            }

            if (isNumeric)
            {
                sout = sin.Substring(i + 1);
                sin = sin.Substring(0, i + 1);
                int.TryParse(sin, out x);
            }

            return false;
        }
    }

您可以将字符串预处理为多个部分,然后使用Linq:

var list = new List<string>{"1", "2", "3", "10", "20", "30", "Dog", "Cat", "30Dog", "30Cat"};

var regEx = new Regex(@"^\d+");

var sorted = list
    .Select(x => new { text = x, intPart = regEx.Match(x).Value })
    .Select(x => new { text = x.text, intPart = string.IsNullOrEmpty(x.intPart) ? int.MaxValue : int.Parse(x.intPart) })
    .OrderBy(x => x.intPart)
    .ThenBy(x => x.text)
    .Select(x => x.text);

sorted.Dump();
var list=新列表{“1”、“2”、“3”、“10”、“20”、“30”、“狗”、“猫”、“30狗”、“30猫”};
var regEx=new regEx(@“^\d+”);
var排序=列表
.Select(x=>new{text=x,intPart=regEx.Match(x).Value})
.Select(x=>new{text=x.text,intPart=string.IsNullOrEmpty(x.intPart)?int.MaxValue:int.Parse(x.intPart)})
.OrderBy(x=>x.intPart)
.ThenBy(x=>x.text)
.选择(x=>x.text);
sorted.Dump();

这是显而易见的;问题是如何编写具有该功能的自定义比较器。对不起。我误解了这个问题,因为你在第三段用英语写了算法。
var list = new List<string>{"1", "2", "3", "10", "20", "30", "Dog", "Cat", "30Dog", "30Cat"};

var regEx = new Regex(@"^\d+");

var sorted = list
    .Select(x => new { text = x, intPart = regEx.Match(x).Value })
    .Select(x => new { text = x.text, intPart = string.IsNullOrEmpty(x.intPart) ? int.MaxValue : int.Parse(x.intPart) })
    .OrderBy(x => x.intPart)
    .ThenBy(x => x.text)
    .Select(x => x.text);

sorted.Dump();