我怎样才能sorting一个string文本后面跟着一个数字使用LINQ
我一直在使用以下种类:
var query = _cityRepository.GetAll( .OrderBy(item => item.RowKey.Substring(0, 4)) .ThenBy(item => item.ShortTitle)
但是我有一个问题,因为我的ShortTitle看起来像这样:
Liverpool - 1 Liverpool - 2 ... Liverpool - 9 Liverpool - 10 Liverpool - 11 West Kirby - 1 West Kirby - 8 West Kirby - 12
当我使用LINQ对它进行sorting时,它是按顺序排列的
Liverpool - 1 Liverpool - 11 Liverpool - 12 Liverpool - 2 West Kirby - 1 West Kirby - 12 West Kirby - 8
ShortTitle总是一连串的单词,然后是一个连字符,然后是一个数字。
有没有一种方法可以让这个sorting正确?
这是因为你将它们sorting为string,并且string11在2之前。你需要parsingShortTitle
来给你(我假设)最后的int
值,然后sorting。
您的LINQ查询可以更改为这个工作:
var query = _cityRepository.GetAll( .OrderBy(item => item.RowKey.Substring(0, 4)) .ThenBy(item => item.ShortTitle.Split('-').First()) .ThenBy(item => Convert.ToInt16(item.ShortTitle.Split().Last()));
尝试这个
List<string> list = new List<string>() { "Liverpool - 1", "Liverpool - 11", "Liverpool - 12", "Liverpool - 2", "West Kirby - 1", "West Kirby - 12", "West Kirby - 8" }; var sortedList = list.CustomSort().ToArray(); public static class MyExtensions { public static IEnumerable<string> CustomSort(this IEnumerable<string> list) { int maxLen = list.Select(s => s.Length).Max(); return list.Select(s => new { OrgStr = s, SortStr = Regex.Replace(s, @"(\d+)|(\D+)", m => m.Value.PadLeft(maxLen, char.IsDigit(m.Value[0]) ? ' ' : '\xffff')) }) .OrderBy(x => x.SortStr) .Select(x => x.OrgStr); } }
快速和肮脏:
class Program { static void Main(string[] args) { var list = new[] {"Liverpool - 1", "Liverpool - 11", "Liverpool - 123", "Liverpool - 342", "Liverpool - 2"}; foreach (var x in list.OrderBy(s => Int32.Parse(Regex.Match(s, @"- (\d*)").Groups[1].Value))) Console.WriteLine(x); } }
晚会晚了,但我不会让我阻止的!
搭载@NominSim的不错解决scheme:
var query = _cityRepository.GetAll() .Select(item => { var fields = item.ShortTitle.Split('-'); return new { Key = item.RowKey.Substring(0,4), Title = fields[0].Trim(), Index = Convert.ToInt16(fields[1]) } }) .OrderBy(item => item.Key) .ThenBy(item => item.Title) .ThenBy(item => item.Index);
真的,主要区别是捕获分割的结果,以便我们不必再次进行分割以获得索引,然后向标题添加了Trim()。
您可以创build自己的比较器,并将其传递给OrderBy或ThenBy,让它们以您想要的方式对string进行sorting。
例如,这个非常原始的比较器,将在转换string之前用0填充最后一个数字:
class MyComparer:Comparer<string> { public override int Compare(string x, string y) { var xL = xparts[xparts.Length - 1]; long xN; if (long.TryParse(xL,out xN)) { xparts[xparts.Length - 1] = xN.ToString().PadLeft(20,'0'); } var yL = yparts[yparts.Length - 1]; long yN; if (long.TryParse(yL, out yN)) { yparts[yparts.Length - 1] = yN.ToString().PadLeft(20, '0'); } var x2=String.Join(" ", xparts); var y2 = String.Join(" ", yparts); return x2.CompareTo(y2); } }
你可以用最小的改变来调用它:
var query = _cityRepository.GetAll( .OrderBy(item => item.RowKey.Substring(0, 4)) .ThenBy(item => item.ShortTitle, new MyComparer());