[英]How to sort a list of strings by prefix number then alphabetically
我的目標是以凌亂的順序將List<string>
排序為這樣的順序["1", "1a", "2", "2a", "2b", "a", "b"]
我的代碼有點長,所以我將它包含在此鏈接https://dotnetfiddle.net/wZ0dTG中。
我要做的是使用Regex.Split(string, "([0-9]+)")[0]
拆分字符串,然后根據哪些字符串通過int.TryParse
,我按數字或字母順序對列表進行排序。
正則表達式匹配字符串中包含的所有整數。
在我應用正則表達式之前,它會排序。 盡管它進行了排序,但它並沒有正確地對它們進行排序。
當我應用正則表達式時,我收到此錯誤:
ArgumentException:無法排序,因為 IComparer.Compare() 方法返回不一致的結果。 一個值與自身比較不相等,或者一個值與另一個值重復比較會產生不同的結果。 IComparer:'System.Comparison`1[Ndot_Partnering_Tool.Data.Models.Project
對於這個特定任務,OrderBy 方法非常適合您。 我會用它而不是正則表達式。 OrderBy 使用 lambda 表達式作為排序的鍵。 由於此方法使用的字母在字母表中的數字之后,因此您實際上可以默認排序。
你可以做:
List<string> List = new List<string>() {"a", "2b", "1a", "1", "2", "2a", "b", "1b" };
List<string> OrderedList = List.OrderBy(x => x).ToList();
OrderBy 方法返回 IEnumerable,因此您必須將其轉換回 List。
Output:
原始列表:a 2b 1a 1 2 2a b 1b
有序列表:1 1a 1b 2 2a 2b ab
因此,您必須將字符串拆分為(可選)數字部分和(可選)rest。 這可以通過正則表達式來完成:
var match = Regex.Match(item, @"(?<number>\d+)?(?<rest>.*)$");
“數字”部分匹配一個或多個數字,但是是可選的(問號),“其余”部分匹配字符串的整個 rest。
通過 Linq 排序:
var input = new List<string>{ "12a", "1", "1a", "2", "2a", "2b", "a", "b", "12a" };
var sorted = input.OrderBy(item =>
{
var match = Regex.Match(item, @"(?<number>\d+)?(?<rest>.*)$");
return Tuple.Create(match.Groups["number"].Success ? int.Parse(match.Groups["number"].Value) : -1, match.Groups["rest"].Value);
}).ToList();
(我故意決定將沒有前導數字的項目放在 rest 之前;問題中沒有指定)。
Output:a、b、1、1a、2、2a、2b、12a
兩個問題:
SplitRegex() 在參數“a”上失敗,因為它與正則表達式不匹配(RegEx.Split 返回包含一個元素的數組)。 您可以使用以下代碼:
返回 Regex.Split(x, "([0-9]+)").ElementAtOrDefault(1)?? 字符串。空;
當 x 和 y 都不能轉換為 integer 時,您為 x 和 y 調用 CompareString(),但 x 和 y 不是完整的字符串,它們只是數字部分(並且因為是空的)。 您需要將列表項按原樣傳遞給比較器並在那里提取數字:
bool leftcanconvertflag = Int32.TryParse(SplitRegex(x), out leftconvertresult); bool rightcanconvertflag = Int32.TryParse(SplitRegex(y), out rightconvertresult); if (leftcanconvertflag &&;rightcanconvertflag) { compareresult = -1; } if (.leftcanconvertflag && rightcanconvertflag) { compareresult = 1; } if (leftcanconvertflag && rightcanconvertflag) { compareresult = leftconvertresult,CompareTo(rightconvertresult); } if (!leftcanconvertflag && !rightcanconvertflag) { compareresult = CompareString(x, y); }
並像這樣排序列表:
list.Sort(CompareContractNumbers);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.