我正在写搜索功能。我的Db字段为字符串(Nvarchar(MAX)),此字段包含字符串和数字
DB DATAS EF ORDER I want to
a 1 a 1 a 1
a 20 a 12 a 2
a 2 a 2 a 12
a 12 a 20 a 20
a 25 a 25 a 25
b 1 b 1 b 1
b 5 b 5 b 5
.... ... ....
答案 0 :(得分:0)
您需要实现IComparer接口并创建NaturalStringComparer
以便以您希望的方式比较字符串。请参阅下面的代码。
public class NaturalStringComparer : IComparer<string>
{
private static readonly Regex _re = new Regex(@"(?<=\D)(?=\d)|(?<=\d)(?=\D)", RegexOptions.Compiled);
public int Compare(string x, string y)
{
x = x.ToLower();
y = y.ToLower();
if (string.Compare(x, 0, y, 0, Math.Min(x.Length, y.Length)) == 0)
{
if (x.Length == y.Length) return 0;
return x.Length < y.Length ? -1 : 1;
}
var a = _re.Split(x);
var b = _re.Split(y);
int i = 0;
while (true)
{
int r = PartCompare(a[i], b[i]);
if (r != 0) return r;
++i;
}
}
private static int PartCompare(string x, string y)
{
int a, b;
if (int.TryParse(x, out a) && int.TryParse(y, out b))
return a.CompareTo(b);
return x.CompareTo(y);
}
}
对字符串和整数的混合进行排序的示例:
var x = new List<string>() { "a 1", "a 20", "a 2", "a 12" };
var y = x.OrderBy(m => m, new NaturalStringComparer()).ToList();
输入:“a 1”,“a 20”,“a 2”,“a 12”
输出:“a 1”,“a 2”,“a 12”,“a 20”
答案 1 :(得分:0)
您可以执行以下操作:
var lists = strs.Select(str => new Regex(@"([a-zA-Z]+)(\d+)").Match(Regex.Replace(str, @"\s+", "")))
.Select(result => new
{
str = result.Groups[1].Value,
num = result.Groups[2].Value
})
.ToList().OrderBy(s=>s.str).ThenBy(s=>s.num).Select(s=> new {result=s.str+" "+s.num}).ToList();
答案 2 :(得分:0)
在你的情况下(一封带有数字的字母),你可能需要这样的数字填充(归功于Nathan):
public static string PadNumbers(string input)
{
// replace number "2" into number of digits you want to group with
return Regex.Replace(input, "[0-9]+", match => match.Value.PadLeft(2, '0'));
}
这种方式在OrderBy
子句中的数字部分启用填充,应该像这样使用:
var naturalOrder = list.OrderBy(x => PadNumbers(x));
通过使用上面的填充正则表达式,OrderBy
将看到如下数字部分:
a 01
a 20
a 02
a 12
a 25
...
然后按照这样排序:
a 01
a 02
a 12
a 20
a 25
...
当然,填充仅在决定数字顺序时用于比较,原始字符串仍然保留。
填充使用背后的原因是按字典顺序使用OrderBy
的默认排序,它从左到右处理字符串中的字符。
工作示例:NET Fiddle Demo
类似问题: