我想对有时包含数字值的字符串列表进行排序
我的列表是这样的:
如果我只是使用orderby: roomList.OrderBy(x => x.Name) 我得到以下列表:
是否可以像这样获取列表?
所有列表元素都不包含数字,并且列表长约1500行
我尝试使用此代码,它在包含数字的元素上工作正常,而在仅包含字符串的元素上不起作用:
public class SemiNumericComparer : IComparer<string>
{
public int Compare(string s1, string s2)
{
if (IsNumeric(s1) && IsNumeric(s2))
{
if (Convert.ToInt32(s1) > Convert.ToInt32(s2)) return 1;
if (Convert.ToInt32(s1) < Convert.ToInt32(s2)) return -1;
if (Convert.ToInt32(s1) == Convert.ToInt32(s2)) return 0;
}
if (IsNumeric(s1) && !IsNumeric(s2))
return -1;
if (!IsNumeric(s1) && IsNumeric(s2))
return 1;
return string.Compare(s1, s2, true);
}
public static bool IsNumeric(object value)
{
try
{
int i = Convert.ToInt32(value.ToString());
return true;
}
catch (FormatException)
{
return false;
}
}
}
答案 0 :(得分:3)
尝试遵循自定义IComparable:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication107
{
class Program
{
static void Main(string[] args)
{
List<string> input = new List<string>() { "1 Light", "1 Paper", "Bathroom 1", "Bathroom 2", "Bathroom 10", "Bedroom 1", "Bedroom 2", "Bedroom 10" };
List<string> results = input.Select(x => new { s = x, order = new Order(x) }).OrderBy(x => x.order).Select(x => x.s).ToList();
}
}
public class Order : IComparable<Order>
{
List<string> split { get; set; }
public Order(string line)
{
split = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
public int CompareTo(Order other)
{
int min = Math.Min(split.Count, other.split.Count);
int thisNumber = 0;
int otherNumber = 0;
for (int i = 0; i < min; i++)
{
if (split[i] != other.split[i])
{
if ((int.TryParse(split[i], out thisNumber)))
{
if ((int.TryParse(other.split[i], out otherNumber)))
{
return thisNumber.CompareTo(otherNumber); //both numbers
}
else
{
return -1; // this is number other is string : this comes first
}
}
else
{
if ((int.TryParse(other.split[i], out otherNumber)))
{
return 1; //other is number this is string : other comes first
}
else
{
return split[i].CompareTo(other.split[i]);
}
}
}
}
return split.Count.CompareTo(other.split.Count);
}
}
}
答案 1 :(得分:2)
[SuppressUnmanagedCodeSecurity]
internal static class SafeNativeMethods
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int StrCmpLogicalW(string p1, string p2);
}
public sealed class StringComparer : IComparer<string>
{
public int Compare(string a, string b)
{
return SafeNativeMethods.StrCmpLogicalW(a, b);
}
}
现在您可以在OrderBy
上使用 StringComparer 了:
List<string> str = new List<string>
{
"Bedroom 1",
"Bedroom 2",
"Bedroom 10",
"Bathroom 1",
"Bathroom 2",
"Bathroom 10",
"1 Light",
"1 Paper"
};
str = str.OrderBy(x => x, new StringComparer()).ToList();
答案 2 :(得分:1)
您正在寻找一种“自然排序”算法
例如: https://www.codeproject.com/Articles/22517/Natural-Sort-Comparer