이 문제는이 목록을 정렬의 필요성을 제거로
int x = points.Min(p => p.X);
var result = points.First(p => p.X == x);
를 사용하는 것이 더 좋습니다 (즉, 그것은 반대로 O(n)
되는, 말, O(n log n)
). 또한 OrderBy
및 First
을 사용하는 것보다 명확합니다.
다음과 같이 더욱 확장 메서드를 작성할 수
static class IEnumerableExtensions {
public static T SelectMin<T>(this IEnumerable<T> source, Func<T, int> 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<Point> points;
Point minPoint = points.SelectMin(p => p.X);
당신은 여러분의 필요에 일반화 할 수 있습니다. 이것의 장점은 잠재적으로 목록을 두 번 걷는 것을 피할 수 있다는 것입니다.
내 논리가 실패하지 않는 한 .Min()은 모든 요소를 검사해야합니까? 그런 다음 그 값을 반환합니다. 먼저 X 값이있는 첫 번째 점을 찾을 때까지 동일한 목록을 다시 시작합니다. 최악의 경우는 2 * n입니까? –
이 문제를 해결하기위한 확장 방법을 추가했습니다. 둘째,'2 * n'은'O (n)'입니다. – jason