如何在 C# 中创建自定义通用数字文本比较器以对 numeric/string 列表进行排序?
How to create custom common number-text comparer in C# to sort numeric/string list?
我有数字文本列表,我想创建通用的自定义比较器逻辑以使用 C# 对此列表进行排序。例如
var numericList = new List<string>{"100", "--", "-0.98", "N/A", "0.00", "-888"};
var stringList = new List<string> {"Smith", "--", "Peter", "", "Jim", "Ken", "NA"};
其中包含一些特殊字符,如 --、N/A、Space 等。排序后的预期结果将是 -
对于 NemericList 升序 -> N/A, -- , -888 , -0.98 , 0.00 , 100
对于 StringList 升序 -> Jim, Ken, N/A, Peter, Smith, Empty, --
我创建了以下自定义比较器逻辑,它进行了某种级别的排序但与预期结果不匹配。请建议我实现这一目标的方法。
public class NumberTextComparer : IComparer<string>
{
public int Compare(string s1, string s2)
{
double number1, number2;
var isS1Numeric = double.TryParse(s1, out number1);
var isS2Numeric = double.TryParse(s2, out number2);
if (isS1Numeric && isS2Numeric)
{
if (number1 > number2) return 1;
if (number1 < number2) return -1;
return 0;
}
return isS1Numeric ? 1 : (isS2Numeric ? -1 : String.Compare(s1, s2, StringComparison.OrdinalIgnoreCase));
}
}
var comparer = new NumberTextComparer();
var numericSortedListASC = numericList.OrderBy(str => str, comparer);
var stringSortedListASC = stringList.OrderBy(str => str, comparer);
您的代码工作正常。硒here。结果:
--, N/A, -888, -0.98, 0.00, 100
, --, Jim, Ken, NA, Peter, Smith
问题在于您的假设,即“”和“--”出现在字母之后。由于他们在 ascii-table 中的位置较低,所以他们排在第一位。
这将是一个简单的修复。尝试 here
public int Compare(string s1, string s2)
{
double number1, number2;
var isS1Numeric = double.TryParse(s1, out number1);
var isS2Numeric = double.TryParse(s2, out number2);
if (isS1Numeric && isS2Numeric)
{
if (number1 > number2) return 1;
if (number1 < number2) return -1;
return 0;
}
if (isS1Numeric)
return 1;
if (isS2Numeric)
return -1;
bool s1StartsWithLetter = char.IsLetter(s1.FirstOrDefault());
bool s2StartsWithLetter = char.IsLetter(s2.FirstOrDefault());
if (s1StartsWithLetter == s2StartsWithLetter)
return String.Compare(s1, s2, StringComparison.OrdinalIgnoreCase);
return s1StartsWithLetter ? -1 : 1;
}
我有数字文本列表,我想创建通用的自定义比较器逻辑以使用 C# 对此列表进行排序。例如
var numericList = new List<string>{"100", "--", "-0.98", "N/A", "0.00", "-888"};
var stringList = new List<string> {"Smith", "--", "Peter", "", "Jim", "Ken", "NA"};
其中包含一些特殊字符,如 --、N/A、Space 等。排序后的预期结果将是 - 对于 NemericList 升序 -> N/A, -- , -888 , -0.98 , 0.00 , 100 对于 StringList 升序 -> Jim, Ken, N/A, Peter, Smith, Empty, --
我创建了以下自定义比较器逻辑,它进行了某种级别的排序但与预期结果不匹配。请建议我实现这一目标的方法。
public class NumberTextComparer : IComparer<string> { public int Compare(string s1, string s2) { double number1, number2; var isS1Numeric = double.TryParse(s1, out number1); var isS2Numeric = double.TryParse(s2, out number2); if (isS1Numeric && isS2Numeric) { if (number1 > number2) return 1; if (number1 < number2) return -1; return 0; } return isS1Numeric ? 1 : (isS2Numeric ? -1 : String.Compare(s1, s2, StringComparison.OrdinalIgnoreCase)); } }
var comparer = new NumberTextComparer();
var numericSortedListASC = numericList.OrderBy(str => str, comparer);
var stringSortedListASC = stringList.OrderBy(str => str, comparer);
您的代码工作正常。硒here。结果:
--, N/A, -888, -0.98, 0.00, 100
, --, Jim, Ken, NA, Peter, Smith
问题在于您的假设,即“”和“--”出现在字母之后。由于他们在 ascii-table 中的位置较低,所以他们排在第一位。
这将是一个简单的修复。尝试 here
public int Compare(string s1, string s2)
{
double number1, number2;
var isS1Numeric = double.TryParse(s1, out number1);
var isS2Numeric = double.TryParse(s2, out number2);
if (isS1Numeric && isS2Numeric)
{
if (number1 > number2) return 1;
if (number1 < number2) return -1;
return 0;
}
if (isS1Numeric)
return 1;
if (isS2Numeric)
return -1;
bool s1StartsWithLetter = char.IsLetter(s1.FirstOrDefault());
bool s2StartsWithLetter = char.IsLetter(s2.FirstOrDefault());
if (s1StartsWithLetter == s2StartsWithLetter)
return String.Compare(s1, s2, StringComparison.OrdinalIgnoreCase);
return s1StartsWithLetter ? -1 : 1;
}