我有一个 100 元素的列表,它们看起来像这样:
此外,我有一个特定的必需订单,让我们说:
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);
但它不起作用。 ThenBy
与第一次排序重叠。
在将int.Parse
输入ThenBy
括号后,我还会获得例外。
帮助我实现这一目标。
答案 0 :(得分:1)
我建议将初始行拆分为匿名类实例:完成此操作(并调试)只需
.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));
结果:
dog
dog (5)
bird (34)
cat (2)
cat + dog (11)
修改:修改了Trim()
中添加的代码OrderBy
; ThenBy
重新设计了
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();
答案 1 :(得分:1)
与使用正则表达式的@Dmitry Bychenko完全相同的答案:
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();
答案 2 :(得分:0)
没有做过检查......数据是完美的,或者一切都在蓬勃发展:
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
)