简体   繁体   English

如何在 C# .net 中对包含带有字母和数字的字符串进行降序排序?

[英]How to sort descending a string list contains strings with alphabets & numbers in C# .net?

I have values in a string list like我在字符串列表中有值,例如

AB1001_A
AB1001_B
AB1002_2
AB1002_C
AB1003_0
AB1003_
AB1003_B
AB1003_A
AB1001_0
AB1001_1
AB1001_2
AB1001_C
AB1002_B
AB1002_A

And I wanted to sort this by ascending order and the suffixes in descending order like below我想按升序和后缀按降序排序,如下所示

AB1001_2
AB1001_1
AB1001_0
AB1001_C
AB1001_B
AB1001_A
AB1002_0
AB1002_B
AB1002_A
AB1003_0
AB1003_B
AB1003_A
AB1003_

How can I code it in C#.net?如何在 C#.net 中对其进行编码?

It is quite strange sorting, but if you really need it, try something like this:这是很奇怪的排序,但如果你真的需要它,试试这样的:

List<string> lItemsOfYourValues = new List<string>() {"AB1001_A","AB1001_B","AB1001_0" /*and next your values*/};

List<Tuple<string,string,string>> lItemsOfYourProcessedValues = new List<Tuple<string,string,string>>();
string[] arrSplitedValue;

for(int i = 0; i < lItemsOfYourValues.Count; i++) 
{

arrSplitedValue = lItemsOfYourValues[i].Split("_");

lItemsOfYourProcessedValues.add(new Tuple<string,string,string>(lItemsOfYourValues[i], arrSplitedValue[0], arrSplitedValue[1]));

}

List<string> lSortedValues = lItemsOfYourProcessedValues.OrderBy(o => o.Item2).ThenByDescending(o => o.Item3).Select(o => o.Item1).ToList();

It looks like you have an error in your expected results, since AB1002_2 is in the input but not in the expected results.看起来您的预期结果有误,因为AB1002_2在输入中但不在预期结果中。

Assuming that's just an error, and further assuming that the suffixes are limited to a single character or digit, you can solve the sorting by writing a special comparer like so:假设这只是一个错误,并进一步假设后缀仅限于单个字符或数字,您可以通过编写一个特殊的比较器来解决排序问题,如下所示:

static int compare(string x, string y)
{
    var xParts = x.Split('_', StringSplitOptions.RemoveEmptyEntries);
    var yParts = y.Split('_', StringSplitOptions.RemoveEmptyEntries);

    if (xParts.Length != yParts.Length)
        return yParts.Length - xParts.Length; // No suffix goes after suffix.

    if (xParts.Length == 0) // Should never happen.
        return 0;

    int comp = string.Compare(xParts[0], yParts[0], StringComparison.Ordinal);

    if (comp != 0 || xParts.Length == 1)
        return comp;

    if (char.IsDigit(xParts[1][0]) && !char.IsDigit(yParts[1][0]))
        return -1; // Digits go before non-digit.

    if (!char.IsDigit(xParts[1][0]) && char.IsDigit(yParts[1][0]))
        return 1; // Digits go before non-digit.

    return string.Compare(yParts[1], xParts[1], StringComparison.Ordinal);
}

Which you can then use to sort a string list, array or IEnumerable<string> , like so:然后您可以使用它对字符串列表、数组或IEnumerable<string>进行排序,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;

namespace Demo
{
    static class Program
    {
        static void Main()
        {
            var strings = new []
            {
                "AB1001_A",
                "AB1001_B",
                "AB1002_2",
                "AB1002_C",
                "AB1003_0",
                "AB1003_",
                "AB1003_B",
                "AB1003_A",
                "AB1001_0",
                "AB1001_1",
                "AB1001_2",
                "AB1001_C",
                "AB1002_B",
                "AB1002_A",
            };

            static int compare(string x, string y)
            {
                var xParts = x.Split('_', StringSplitOptions.RemoveEmptyEntries);
                var yParts = y.Split('_', StringSplitOptions.RemoveEmptyEntries);

                if (xParts.Length != yParts.Length)
                    return yParts.Length - xParts.Length;

                if (xParts.Length == 0)
                    return 0;

                int comp = string.Compare(xParts[0], yParts[0], StringComparison.Ordinal);

                if (comp != 0 || xParts.Length == 1)
                    return comp;

                if (char.IsDigit(xParts[1][0]) && !char.IsDigit(yParts[1][0]))
                    return -1; // Digits go before non-digit.

                if (!char.IsDigit(xParts[1][0]) && char.IsDigit(yParts[1][0]))
                    return 1; // Digits go before non-digit.

                return string.Compare(yParts[1], xParts[1], StringComparison.Ordinal);
            }

            var stringList = strings.ToList();
            stringList.Sort(compare);

            Console.WriteLine("Sorted list:");
            Console.WriteLine(string.Join("\n", stringList));

            var stringArray = strings.ToArray();
            Array.Sort(stringArray, compare);

            Console.WriteLine("\nSorted array:");
            Console.WriteLine(string.Join("\n", stringArray));

            var sequence = strings.Select(element => element);
            var sortedSeq = sequence.OrderBy(element => element, Comparer<string>.Create(compare));

            Console.WriteLine("\nSorted sequence:");
            Console.WriteLine(string.Join("\n", sortedSeq));
        }
    }
}

Try it online on .Net Fiddle在 .Net Fiddle 上在线试用

Finally I got the soln by this最后我得到了这个解决方案

var mystrings = new []
            {
                "AB1001_A",
                "AB1001_B",
                "AB1002_2",
                "AB1002_C",
                "AB1003_0",
                "AB1003_",
                "AB1003_B",
                "AB1003_A",
                "AB1001_0",
                "AB1001_1",
                "AB1001_2",
                "AB1001_C",
                "AB1002_B",
                "AB1002_A",
            };


mystrings.Cast<string>().OrderBy(x => PadNumbers(x));

and then PadNumbers function as like below然后 PadNumbers 功能如下

        public static string PadNumbers(string input)
        {
            return Regex.Replace(input, "[0-9]+", match => match.Value.PadLeft(10, '0'));
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM