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?
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.
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:
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));
}
}
}
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
public static string PadNumbers(string input)
{
return Regex.Replace(input, "[0-9]+", match => match.Value.PadLeft(10, '0'));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.