4

大家!如何在 C# 中获取特定范围内的 int 数组的最小值?例如: int[] array= new int{1,2,3,4,5,6,7,8,76,45}; 我想获得第 3 和第 8 元素之间的最小值。也许可以通过 LINQ 查询获得?

4

7 回答 7

13
array.Skip(2).Take(5).Min();
于 2010-12-10T19:36:58.077 回答
6

我想我不妨把我的 tuppence 添加到此。Jason 反对我们说的是跳过了多少而不是结束索引,我们可以添加一个简单的扩展方法:

public static IEnumerable<T> WithIndexBetween<T>(this IEnumerable<T> source,
    int startInclusive, int endExclusive)
{
    // The two values can be the same, yielding no results... but they must
    // indicate a reasonable range
    if (endExclusive < startInclusive)
    {
        throw new ArgumentOutOfRangeException("endExclusive");
    }
    return source.Skip(startInclusive).Take(endExclusive - startInclusive);
}

然后:

int min = array.WithIndexBetween(2, 7).Min();

调整扩展方法名称以适应口味。(命名很难,我不会花很多时间在这里想出一个好名字:)

于 2010-12-10T20:05:06.807 回答
3
int min = array.Where((value, index) => index >= 2 && index <= 7).Min(); 

编辑

实际上,上面的方法效率很低,因为它枚举了整个序列,即使我们对索引高于 7 的项目不感兴趣。更好的解决方案是使用TakeWhile

int min = array.TakeWhile((value, index) => index <= 7).Skip(2).Min();

不幸的是,它的可读性不是很好......让它变得更好的最佳选择可能是创建一个自定义扩展方法,如 Jon 的回答所示。

于 2010-12-10T19:36:44.627 回答
3
int[] arr = {0,1,2,3,4,5,6,7,8};
int start = 3;
int end = 8;
int min = arr.Skip(start - 1).Take(end - start).Min();
于 2010-12-10T19:38:12.767 回答
2

只是添加另一个选项:

int start = 3;
int end = 8;
var min = Enumerable.Range(start - 1,end - start).Select(idx => array[idx]).Min();

AFAIK,如果你必须在一个接近末端的范围内取一个范围,这“理论上”会更快,而且你的数组真的很长。

那是因为(再次AFAIK)Skip()没有考虑到它是一个数组(即可以在O(1)中随机访问)并且无论如何都要枚举它。

于 2010-12-10T19:58:47.597 回答
0

就个人而言,我更喜欢这个:

public static class ArrayExtensions {
    public static bool ArrayAndIndexesAreValid(
        T[] array,
        int startInclusive,
        int endExclusive
    ) {
    return array != null &&
           array.Length > 0 &&
           startInclusive >= 0 && startInclusive < array.Length &&
           endExclusive >= 1 && endExclusive <= array.Length &&
           startInclusive < endExclusive;
    }
    public static IEnumerable<T> Slice<T>(
        this T[] array,
        int startInclusive,
        int endExclusive
    ) {
        Contract.Requires<ArgumentException>(ArrayAndIndexesAreValid(
            array,
            startInclusive,
            endExclusive)
        );
        for (int index = startInclusive; index < endExclusive; index++) {
            yield return array[index];
        }
    }
    public static T MinimumInIndexRange<T>(
        this T[] array,
        int startInclusive,
        int endExclusive
    ) where T : IComparable {
        Contract.Requires<ArgumentException>(ArrayAndIndexesAreValid(
            array,
            startInclusive,
            endExclusive)
        );
        return array.Slice(startInclusive, endExclusive).Min();
    }

    public static T MaximumInIndexRange<T>(
        this T[] array,
        int startInclusive,
        int endExclusive
    ) where T : IComparable {
        Contract.Requires<ArgumentException>(ArrayAndIndexesAreValid(
            array,
            startInclusive,
            endExclusive)
        );
        return array.Slice(startInclusive, endExclusive).Max();
    }
}
于 2010-12-10T20:23:04.433 回答
0
array.Skip(3).Take(4).Min();
于 2010-12-10T19:39:10.623 回答