请帮我处理字符串排序。
我有一个List,其中包含Oracle数据库select语句的结果。一般来说,它看起来像这样:
"9",
"10 k. 1 str. 1",
"10 k. 2 str. 1",
"11 k.1",
"12",
"12 k.1 str. 2"
但当然没那么好。
我可以使用LINQ查询对其进行排序,例如:
var oLst = lst.OrderBy(x => int.Parse(x.Split(' ')[0])).ToList();
它对此列表进行排序,但仅限于第一个整数。我想做的是某种"条件的ThenBy()"基于x.Split(' ')[2]
字符串元素的存在进行排序,但我无法弄清楚如何进行排序。我想要的是先排序"首先"字符串中的整数,如果它们存在 - 由第二个,然后是第三个。
var oLst = lst.OrderBy(x => int.Parse(x.Split(' ')[0])).ThenBy(x => int.Parse(x.Split(' ')[2])).ThenBy(x => int.Parse(x.Split(' ').Last())).ToList();
仅适用于"完整字符串"它具有所有整数值,但如何在列表的某些字符串中不存在此Split(' ')[]
元素的情况下管理这种情况?
答案 0 :(得分:1)
您可以实现比较器:
public class NumberExtractorComparer : IComparer<MatchCollection>
{
private static readonly Regex rx = new Regex("[0-9]+");
public static readonly NumberExtractorComparer Comparer = new NumberExtractorComparer();
// Returns a MatchCollection composed of all the groups of
// digits
public static MatchCollection Selector(string str)
{
return rx.Matches(str);
}
// Compares two matchcollections
public int Compare(MatchCollection x, MatchCollection y)
{
int min = Math.Min(x.Count, y.Count);
for (int i = 0; i < min; i++)
{
// Using long to support bigger numbers
long l1 = long.Parse(x[i].Value);
long l2 = long.Parse(y[i].Value);
int cmp = l1.CompareTo(l2);
if (cmp != 0)
{
return cmp;
}
}
return x.Count.CompareTo(y.Count);
}
}
然后
var res = lst
.OrderBy(
NumberExtractorComparer.Selector,
NumberExtractorComparer.Comparer)
.ToArray();
请注意,我在进行比较之前(NumberExtractorComparer.Selector
)正在提取数字(NumberExtractorComparer.Comparer
)。这样,对于集合的每个元素,数字将只被提取一次(与比较部分相比,数字提取可能非常慢)
答案 1 :(得分:0)
您可以从字符串中提取数字并按数字值排序。
var oLst = lst.OrderBy(x => int.Parse(Regex.Replace(x, "[^0-9]", ""))).ToList();
答案 2 :(得分:0)
您可以将字符串转换为double,然后按该double进行排序。例如:
"9" => 9.0
"10 k. 1 str. 1" => 10.11
"10 k. 2 str. 1" => 10.21
"11 k.1" => 11.0
"12" => 12.0
"12 k.1 str. 2 => 12.2
实现这一诀窍的方法是:
Parse(string str)
{
double res = 0;
string[] p = str.Split(' ');
double multuplier = 1.0;
p.ToList().ForEach(f =>
{
int parsed;
if(int.TryParse(f, out parsed))
{
res += parsed * multuplier;
multuplier *= 0.1;
}
});
return res;
}
然后只使用:
List<string> ordered = lst.OrderBy(Parse).ToList();
答案 3 :(得分:0)
var query = from x in source
let tokens = x.Split(' ')
order by
GentlyParse(tokens.FirstOrDefault()),
GentlyParse(tokens.Skip(2).FirstOrDefault()),
GentlyParse(tokens.LastOrDefault())
select x;
var results = query.ToList();
GentlyParse是一个你需要编写的方法,它接受一个字符串(或null)并返回可以解析的int或null。