如何在不使用OrderBy的情况下从Point数组中获取具有最小X的Point?

想象一下,我有

var points = new Point[] { new Point(1, 2), new Point(2, 3) }; 

要获得最小XI的要点可以:

  var result = points.OrderBy(point => point.X).First(); 

但对于大型arrays,我认为这不是更快的选择。 还有更快的选择吗?

最好使用

 int x = points.Min(p => pX); var result = points.First(p => pX == x); 

因为这消除了对该列表进行排序的必要性(即,它是O(n)而不是O(n log n) )。 此外,它比使用OrderByFirst更清楚。

您甚至可以编写扩展方法,如下所示:

 static class IEnumerableExtensions { public static T SelectMin(this IEnumerable source, Func selector) { if (source == null) { throw new ArgumentNullException("source"); } int min = 0; T returnValue = default(T); bool flag = false; foreach (T t in source) { int value = selector(t); if (flag) { if (value < min) { returnValue = t; min = value; } } else { min = value; returnValue = t; flag = true; } } if (!flag) { throw new InvalidOperationException("source is empty"); } return returnValue; } 

用法:

 IEnumerable points; Point minPoint = points.SelectMin(p => pX); 

您可以概括您的需求。 这样做的好处是它可以避免两次潜在的列表。

以下应该是最快的,但不是最漂亮的方式:

 public static T MinValue(this IEnumerable e, Func f) { if (e == null) throw new ArgumentException(); var en = e.GetEnumerator(); if (!en.MoveNext()) throw new ArgumentException(); int min = f(en.Current); T minValue = en.Current; int possible = int.MinValue; while (en.MoveNext()) { possible = f(en.Current); if (min > possible) { min = possible; minValue = en.Current; } } return minValue; } 

我只包含了int扩展,但是做其他人是微不足道的。

编辑:根据杰森修改。

对于今天想要这样做的人, MoreLinq是NuGet提供的库,其中包括其他答案提供的运算符以及框架中没有的其他一些有用的操作。