簡體   English   中英

如何按前綴編號然后按字母順序對字符串列表進行排序

[英]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

兩個問題:

  1. SplitRegex() 在參數“a”上失敗,因為它與正則表達式不匹配(RegEx.Split 返回包含一個元素的數組)。 您可以使用以下代碼:

    返回 Regex.Split(x, "([0-9]+)").ElementAtOrDefault(1)?? 字符串。空;

  2. 當 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM