请考虑以下事项:
new[] {
new { A = 3, B = 3 },
new { A = 2, B = 2 },
new { A = 2, B = 2 },
new { A = 1, B = 1 }
}
.OrderBy(x => x.A)
.ThenBy(x => x.B)
.ToList();
此List
将按以下顺序包含以下数据:
[{A = 1,B = 1},{A = 2,B = 2},{A = 2,B = 2},{A = 3,B = 3}]
如何确定项1
和2
相等?我想要'当所有throw
/ OrderBy
语句执行且仍有相同的项目(无法排序)时,我的代码ThenBy
。
注意,想象这些项目非常复杂(具有很多属性),并且有一百万个OrderBy
/ ThenBy
语句,以及一个很多数据。我宁愿避免再次迭代数据。
答案 0 :(得分:3)
您可以在之前进行排序。识别重复项的最简单方法是使用FormHome
。
由于您使用匿名类型,因此您可以按项目本身进行分组:
GroupBy
如果您不在现实中使用匿名类型,那么只需按照您要用来定义"相等的属性进行分组。
您还可以检查连续重复"内联"使用扩展方法:
var data =
new[] {
new { A = 3, B = 3 },
new { A = 2, B = 2 },
new { A = 2, B = 2 },
new { A = 1, B = 1 }
};
var groups = data.GroupBy(x => x); // works since we are using anonymous types that use value equality
if(groups.Any(g => g.Count() > 1)
{
// throw exception
}
var result = groups.Select(g=>g.Key)
.OrderBy(x => x.A)
.ThenBy(x => x.B)
.ToList();
在 public static IEnumerable<T> ThrowIfConsecutiveItemsAreEqual<T>(this IEnumerable<T> source)
{
bool isFirst = true;
T prev = default(T);
foreach(var item in source)
{
if(!isFirst && item.Equals(prev))
throw new Exception(); // TODO: use a better exception type and message
yield return item;
isFirst = false;
prev = item;
}
}
之前调用扩展方法以避免多次枚举:
ToList
答案 1 :(得分:0)
为了以这种方式查找重复项,您只需要在排序后查看上一项:
static IEnumerable<C> Deduplicate(this IEnumerable<C> items) {
C last = null;
foreach (var item in items) {
if (last != null && last.A == item.A && last.B == item.B) {
//duplicate, handle as you like
}
last = item;
yield return item;
}
有各种方法来分解这种逻辑,但这是基本的想法。我发现编写一个帮助迭代器会很有用,它会返回相同的序列,但每个项目的前一个项目。使用该帮助程序,您不再需要编写自定义迭代器。