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

これにタペンスを加えたほうがいいと思います。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
array.Skip(3).Take(4).Min();
于 2010-12-10T19:39:10.623 に答える
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 に答える