C# 对包含字符串和/或数字的集合进行排序
我有一个100个元素的列表,看起来像这样:C# 对包含字符串和/或数字的集合进行排序,c#,linq,sorting,C#,Linq,Sorting,我有一个100个元素的列表,看起来像这样: bool equal = collection .OrderBy(i => Array.IndexOf(order, i.Split('(').First())) .ThenBy(i => i.Split('(').Last().Replace(")", " ")) .SequenceEqual(collection2); 狗 猫(2) 伯德(34) 猫+狗(11) 狗(5) 此外,我还有一个特定的要求订单,比如: strin
bool equal = collection
.OrderBy(i => Array.IndexOf(order, i.Split('(').First()))
.ThenBy(i => i.Split('(').Last().Replace(")", " "))
.SequenceEqual(collection2);
string[] order = {"dog", "bird", "cat", "cat + dog"};
我需要我的方法按上述顺序排序,然后按数字排序,得到结果:
bool equal = collection
.OrderBy(i => Array.IndexOf(order, i.Split('(').First()))
.ThenBy(i => i.Split('(').Last().Replace(")", " "))
.SequenceEqual(collection2);
但它不起作用<代码>然后按与第一次排序重叠。
另外,在输入int.Parse
到括号后,我得到一个异常
请帮助我实现这一点。我建议将初始行拆分为匿名类实例:完成(并调试)后,您可以
.OrderBy(item => Array.IndexOf(order, item.name))
.ThenBy(item => item.count)
实施:
List<string> collection = new List<string> {
"dog",
"cat (2)",
"bird (34)",
"cat + dog (11)",
"dog (5)",
};
string[] order = { "dog", "bird", "cat", "cat + dog" };
var result = collection
.Select(item => item.Split('('))
.Select(parts => parts.Length == 1 // do we have "(x)" part?
? new { name = parts[0].Trim(), count = 1 } // no
: new { name = parts[0].Trim(), count = int.Parse(parts[1].Trim(')')) }) // yes
.OrderBy(item => Array.IndexOf(order, item.name)) // now it's easy to work with data
.ThenBy(item => item.count)
.Select(item => item.count == 1 // back to the required format
? $"{item.name}"
: $"{item.name} ({item.count})")
.ToList();
Console.WriteLine( string.Join(Environment.NewLine, result));
编辑:您的代码被修改Trim()
添加到OrderBy
中<代码>然后按
重新设计
var result = collection
.OrderBy(i => Array.IndexOf(order, i.Split('(').First().Trim())) // Trim
.ThenBy(i => i.Contains('(') // two cases:
? int.Parse(i.Split('(').Last().Replace(")", "")) // with "(x)" part
: 1) // without
.ToList();
没有检查完成。。。数据是完美的,或者一切都很顺利:
var res = (from x in collection
let ix = x.LastIndexOf(" (")
orderby Array.IndexOf(order, ix != -1 ? x.Remove(ix) : x),
ix != -1 ? int.Parse(x.Substring(ix + 2, x.Length - 1 - (ix + 2))) : 0
select x).ToArray();
注意
ix!=-1
。在orderby
的第二行中(即函数LINQ中的ThenBy()
),如果ix==-1
,则值为:0
)与使用regex的答案完全相同:
var collection = new List<string> {
"dog",
"cat (2)",
"bird (34)",
"cat + dog (11)",
"dog (5)",
};
string[] order = { "dog", "bird", "cat", "cat + dog" };
var regex = new Regex("^(?<name>.*?)\\s*(\\((?<number>[0-9]+)\\))?$");
var result = collection
.Select(i =>
{
var match = regex.Match(i);
return new {
content = i,
name = match.Groups["name"].Value,
number = int.TryParse(match.Groups["number"].Value, out int number)
? number
: 1 };
})
.OrderBy(item => Array.IndexOf(order, item.name))
.ThenBy(item => item.number)
.Select(i => i.content)
.ToList();
Console.WriteLine(string.Join(Environment.NewLine, result));
Console.ReadLine();
var集合=新列表{
“狗”,
"第二类",,
"雀鸟(34)",,
“猫+狗(11)”,
"狗只(五)",,
};
字符串[]顺序={“狗”、“鸟”、“猫”、“猫+狗”};
var regex=new regex(“^(?.*?\\s*(\\((?[0-9]+)\\))?$”;
var结果=集合
.选择(i=>
{
var match=regex.match(i);
还新{
content=i,
名称=匹配。组[“名称”]。值,
number=int.TryParse(match.Groups[“number”].值,out int number)
?数量
: 1 };
})
.OrderBy(item=>Array.IndexOf(order,item.name))
.ThenBy(项目=>项目编号)
.选择(i=>i.content)
.ToList();
Console.WriteLine(string.Join(Environment.NewLine,result));
Console.ReadLine();
您是否计划创建自定义比较函数?可能重复的“100个元素列表”元素是字符串“cat(2)”的字面意思,还是具有属性cat
和2
的元素将i.Split(“(”).Last()。替换(“)”,“)为数字帮助?i、 e.bool equal=collection.OrderBy(i=>Array.IndexOf(order,i.Split(“(”).First()).ThenBy(i=>int.Parse(i.Split(“(”).Last().Replace(“)).SequenceEqual(collection2);@Lucifer他还有一个步骤:按另一个数组排序你可以将\s*
添加到模式var regex=new regex(“(?*)\”((?*)\)\((?[0-9])\)\)\);
并摆脱Trim()
:.OrderBy(item=>Array.IndexOf(order,item.name))
因为默认值(int)==0
我怀疑它是否应该被使用;可能它应该是1
:…?数字:1
-如果省略了数量-(数字)
,则提到一只动物:“狗”
-一只狗,“狗(5)”
-五只狗。@DmitryBychenko你说得对,这会让代码更好;-)我还为名称添加了一个非贪婪表达式,否则它会保留空格。