你如何获得int数组中最低值的索引?

考虑到这是一项非常基本的任务,我想不出一个适当的简单方法。 你如何获得int数组中最低值的索引? 使用Linq / MoreLinq是可能的。 到目前为止,我找不到一个合理的单线。

既然你提到了MoreLinq,那怎么样:

int[] array = .. // Will throw if the array is empty. // If there are duplicate minimum values, the one with the smaller // index will be chosen. int minIndex = array.AsSmartEnumerable() .MinBy(entry => entry.Value) .Index; 

另一种选择:

 // Will throw if the array is empty. // Requires two passes over the array. int minIndex = Array.IndexOf(array, array.Min()); 

您当然可以编写自己的扩展方法:

 // Returns last index of the value that is the minimum. public static int IndexOfMin(this IEnumerable source) { if(source == null) throw new ArgumentNullException("source"); int minValue = int.MaxValue; int minIndex = -1; int index = -1; foreach(int num in source) { index++; if(num <= minValue) { minValue = num; minIndex = index; } } if(index == -1) throw new InvalidOperationException("Sequence was empty"); return minIndex; } 

通过一些努力,您可以通过接受IComparer将其概括为任何类型,默认为Comparer.Default

LINQ可能不是解决此问题的最佳解决方案,但这是另一种变体,即O(n)。 它不排序,只遍历数组一次。

 var arr = new int[] { 3, 1, 0, 5 }; int pos = Enumerable.Range(0, arr.Length) .Aggregate((a, b) => (arr[a] < arr[b]) ? a : b); // returns 2 

更新:直接回答原始问题,我就是这样做的:

 var arr = new int[] { 3, 1, 0, 5 }; int pos = 0; for (int i = 0; i < arr.Length; i++) { if (arr[i] < arr[pos]) { pos = i; } } // pos == 2 

不,它不使用LINQ。 是的,它不止一条线。 但它非常简单而且非常快。 将它变成一个小小的方法,并从一行中的任何地方调用它: pos = FindMinIndex(arr);

不是很友好,但……

 array.Select((n, i) => new { index = i, value = n }) .OrderBy(item => item.value) .First().index 

它很丑,但它只需要一次通过序列,只使用内置的框架方法:

 int index = yourArray.Select((x, i) => new { Val = x, Idx = i }) .Aggregate(new { Val = -1, Idx = -1 }, (a, x) => (x.Idx == 0 || x.Val < a.Val) ? x : a, x => x.Idx); 

当然,您可以编写通用扩展方法:

 int index = yourArray.MinIndex(); // ... public static class EnumerableExtensions { public static int MinIndex( this IEnumerable source, IComparer comparer = null) { if (source == null) throw new ArgumentNullException("source"); if (comparer == null) comparer = Comparer.Default; using (var enumerator = source.GetEnumerator()) { if (!enumerator.MoveNext()) return -1; // or maybe throw InvalidOperationException int minIndex = 0; T minValue = enumerator.Current; int index = 0; while (enumerator.MoveNext()) { index++; if (comparer.Compare(enumerator.Current, minValue) < 0) { minIndex = index; minValue = enumerator.Current; } } return minIndex; } } }