如何让 OrderBy 或 IComparer 对我的特定列表进行排序?
How can I get OrderBy or IComparer to sort my particular list?
我最初生成的字典 int
s 运行domly 在 1 - 100 之间的 运行ge 中使用:
var lstNumbers = Enumerable.Range(1, 100).OrderBy(n => Guid.NewGuid)
.GetHashCode()).ToList();
字典已创建并用于将 ColorType
值分配给序列中的每个数字 Red、Yellow、White、Red、Yellow、White 等名单:
var startColor = ColorType.Red;
var map = new Dictionary<int, ColorType>();
foreach(var number in lstNumbers) {
// First color for assignment
map[number] = startColor.Next();
// Go to the next color
startColor = startColor.Next();
}
然后我用几种不同的方式删除项目:
foreach(KeyValuePair<int, ColorType> entry in map.ToList()) {
if (entry.Key % 2 == 0 && entry.Value == ColorType.Red) {
map.Remove(entry.Key);
}
if (entry.Key % 2 == 1 && entry.Value == ColorType.Yellow) {
map.Remove(entry.Key);
}
if (entry.Key % 3 == 0 && entry.Value == ColorType.White) {
map.Remove(entry.Key);
}
}
然后我按升序排列数字:
foreach(var number in map.OrderBy(i => i.Key)) {
Console.WriteLine(number);
}
Console.ReadLine();
所以我的列表现在大致如下所示:
[53, Red]
[54, Yellow]
[55, White]
[56, Yellow]
[61, White]
[62, White]
[64, Yellow]
[65, Red]
ect., ect.
现在我需要按值对字典中的最终列表进行排序,白色结果在顶部,黄色在中间,红色在底部。红色 < 黄色 < 白色,然后显示。
我试过这个 OrderBy
但我可能没有正确实施它或者它可能不适用于我的场景,因为我收到错误:
The == operator can not be applied to operands of 'ColorType' and 'string'.
foreach(var color in map.OrderBy(c => c.Value == "White" ? 0 : c.Value == "Yellow" ? 1 : 2)) {
Console.WriteLine(color);
}
我尝试使用 IComparer
,但我 运行 遇到了问题,因为我在我的字典中使用了用于颜色的自定义类型:
public class CustomerComparer : IComparer<KeyValuePair<int, ColorType>> {
private List<string> orderedColors = new List<string>() { "White", "Yellow", "Red" };
public int Compare(KeyValuePair<int, ColorType> str1, KeyValuePair<int, ColorType> str2) {
return orderedColors.IndexOf(str1.Value) - orderedColors.IndexOf(str2.Value);
}
}
var sorted = map.OrderBy(x => x, new CustomerComparer());
foreach(var entry in sorted) {
Console.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
Console.ReadKey();
我猜有更好的方法,换一种方法,或者我完全遗漏了一些东西。
我认为您在这里不需要自定义比较器。您可以使用 .ThenBy
进行链式排序。
你可以写
var sorted = map.OrderBy(c => c.Value != ColorType.White)
.ThenBy(c => c.Value != ColorType.Yellow)
.ThenBy(c => c.Value != ColorType.Red);
请注意 !=
运算符——您按布尔值排序,因此 false
排在 true
之前。
如您收到的错误所示,您尝试将 ColorType
与 String
进行比较。你需要让两侧相同,要么都 ColorType
:
foreach (var color in map.OrderBy(c => c.Value == ColorType.White ?
0 : c.Value == ColorType.Yellow ? 1 : 2)) {
Console.WriteLine(color);
}
或两者 String
。你说 ColorType
是自定义数据类型,所以我不知道 ToString()
是否会 return 颜色的名称:
foreach (var color in map.OrderBy(c => c.Value.ToString() == "White" ?
0 : c.Value.ToString() == "Yellow" ? 1 : 2)) {
Console.WriteLine(color);
}
例如,如果您使用 System.Drawing.Color
class,ToString()
将不起作用,因为它 return 类似于 Color [Red]
。相反,您可以使用 Name
属性:
foreach (var color in map.OrderBy(c => c.Value.Name == "White" ?
0 : c.Value.Name == "Yellow" ? 1 : 2)) {
Console.WriteLine(color);
}
所以我不知道你的 ColorType
class 是否有与 return 相似的 属性 颜色名称,或者 ToString()
会做的。
我最初生成的字典 int
s 运行domly 在 1 - 100 之间的 运行ge 中使用:
var lstNumbers = Enumerable.Range(1, 100).OrderBy(n => Guid.NewGuid)
.GetHashCode()).ToList();
字典已创建并用于将 ColorType
值分配给序列中的每个数字 Red、Yellow、White、Red、Yellow、White 等名单:
var startColor = ColorType.Red;
var map = new Dictionary<int, ColorType>();
foreach(var number in lstNumbers) {
// First color for assignment
map[number] = startColor.Next();
// Go to the next color
startColor = startColor.Next();
}
然后我用几种不同的方式删除项目:
foreach(KeyValuePair<int, ColorType> entry in map.ToList()) {
if (entry.Key % 2 == 0 && entry.Value == ColorType.Red) {
map.Remove(entry.Key);
}
if (entry.Key % 2 == 1 && entry.Value == ColorType.Yellow) {
map.Remove(entry.Key);
}
if (entry.Key % 3 == 0 && entry.Value == ColorType.White) {
map.Remove(entry.Key);
}
}
然后我按升序排列数字:
foreach(var number in map.OrderBy(i => i.Key)) {
Console.WriteLine(number);
}
Console.ReadLine();
所以我的列表现在大致如下所示:
[53, Red]
[54, Yellow]
[55, White]
[56, Yellow]
[61, White]
[62, White]
[64, Yellow]
[65, Red]
ect., ect.
现在我需要按值对字典中的最终列表进行排序,白色结果在顶部,黄色在中间,红色在底部。红色 < 黄色 < 白色,然后显示。
我试过这个 OrderBy
但我可能没有正确实施它或者它可能不适用于我的场景,因为我收到错误:
The == operator can not be applied to operands of 'ColorType' and 'string'.
foreach(var color in map.OrderBy(c => c.Value == "White" ? 0 : c.Value == "Yellow" ? 1 : 2)) {
Console.WriteLine(color);
}
我尝试使用 IComparer
,但我 运行 遇到了问题,因为我在我的字典中使用了用于颜色的自定义类型:
public class CustomerComparer : IComparer<KeyValuePair<int, ColorType>> {
private List<string> orderedColors = new List<string>() { "White", "Yellow", "Red" };
public int Compare(KeyValuePair<int, ColorType> str1, KeyValuePair<int, ColorType> str2) {
return orderedColors.IndexOf(str1.Value) - orderedColors.IndexOf(str2.Value);
}
}
var sorted = map.OrderBy(x => x, new CustomerComparer());
foreach(var entry in sorted) {
Console.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
Console.ReadKey();
我猜有更好的方法,换一种方法,或者我完全遗漏了一些东西。
我认为您在这里不需要自定义比较器。您可以使用 .ThenBy
进行链式排序。
你可以写
var sorted = map.OrderBy(c => c.Value != ColorType.White)
.ThenBy(c => c.Value != ColorType.Yellow)
.ThenBy(c => c.Value != ColorType.Red);
请注意 !=
运算符——您按布尔值排序,因此 false
排在 true
之前。
如您收到的错误所示,您尝试将 ColorType
与 String
进行比较。你需要让两侧相同,要么都 ColorType
:
foreach (var color in map.OrderBy(c => c.Value == ColorType.White ?
0 : c.Value == ColorType.Yellow ? 1 : 2)) {
Console.WriteLine(color);
}
或两者 String
。你说 ColorType
是自定义数据类型,所以我不知道 ToString()
是否会 return 颜色的名称:
foreach (var color in map.OrderBy(c => c.Value.ToString() == "White" ?
0 : c.Value.ToString() == "Yellow" ? 1 : 2)) {
Console.WriteLine(color);
}
例如,如果您使用 System.Drawing.Color
class,ToString()
将不起作用,因为它 return 类似于 Color [Red]
。相反,您可以使用 Name
属性:
foreach (var color in map.OrderBy(c => c.Value.Name == "White" ?
0 : c.Value.Name == "Yellow" ? 1 : 2)) {
Console.WriteLine(color);
}
所以我不知道你的 ColorType
class 是否有与 return 相似的 属性 颜色名称,或者 ToString()
会做的。